177

I have been trying to initialise a string from NSData in Swift.

In the NSString Cocoa Documentation Apple is saying you have to use this:

 init(data data: NSData!, encoding encoding: UInt)

However Apple did not include any example for usage or where to put the init.

I am trying to convert the following code from Objective-C to Swift

NSString *string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];

I have been trying a lot of possible syntaxes such as the following (of course it did not work):

var string:NSString!
string = init(data: fooData,encoding: NSUTF8StringEncoding)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
ahmed
  • 14,316
  • 30
  • 94
  • 127

7 Answers7

282

This is the implemented code needed:

in Swift 3.0:

var dataString = String(data: fooData, encoding: String.Encoding.utf8)

or just

var dataString = String(data: fooData, encoding: .utf8)

Older swift version:

in Swift 2.0:

import Foundation

var dataString = String(data: fooData, encoding: NSUTF8StringEncoding)

in Swift 1.0:

var dataString = NSString(data: fooData, encoding:NSUTF8StringEncoding)
Sunkas
  • 9,542
  • 6
  • 62
  • 102
228

This is how you should initialize the NSString:

Swift 2.X or older

let datastring = NSString(data: fooData, encoding: NSUTF8StringEncoding)

Swift 3 or newer:

let datastring = NSString(data: fooData, encoding: String.Encoding.utf8.rawValue)

This doc explains the syntax.

MCCCS
  • 1,002
  • 3
  • 20
  • 44
67cherries
  • 6,931
  • 7
  • 35
  • 51
  • 2
    Note that you don’t need to repeat “data” and “encoding” like that. – jbg Jul 07 '14 at 05:36
  • 2
    How can you do that what UInt is a constructor? It's asking me to add brackets. – User Sep 20 '14 at 02:36
  • 19
    Should be `let datastring = NSString(data: fooData, encoding:NSUTF8StringEncoding)` – Yas Tabasam Apr 15 '15 at 21:03
  • 14
    Is it possible to convert `NSData` directly into a Swift `String` (instead of an `NSString`)? – ma11hew28 Jun 29 '15 at 18:45
  • 3
    @MattDiPasquale var swiftString = NSString(data: NSData!, encoding: UInt) as! String that's all – Gintama Aug 29 '15 at 06:52
  • 12
    @MattDiPasquale Ignore the above forced cast; `String` is an `NSString`... all of these should be: `var datastring = String(data: someData, encoding: NSUTF8StringEncoding)` – JRaymond Oct 30 '15 at 00:27
  • @JRaymond NSLog would reject it as argument if you don't cast it. – marsbear Aug 24 '16 at 13:34
15

Swift 2.0

It seems that Swift 2.0 has actually introduced the String(data:encoding:) as an String extension when you import Foundation. I haven't found any place where this is documented, weirdly enough.

(pre Swift 2.0) Lightweight extension

Here's a copy-pasteable little extension without using NSString, let's cut the middle-man.

import Foundation

extension NSData
{
    var byteBuffer : UnsafeBufferPointer<UInt8> { get { return UnsafeBufferPointer<UInt8>(start: UnsafeMutablePointer<UInt8>(self.bytes), count: self.length) }}
}

extension String
{
    init?(data : NSData, encoding : NSStringEncoding)
    {
        self.init(bytes: data.byteBuffer, encoding: encoding)
    }
}

// Playground test
let original = "Nymphs blitz quick vex dwarf jog"
let encoding = NSASCIIStringEncoding

if let data = original.dataUsingEncoding(encoding)
{
    String(data: data, encoding: encoding)
}

This also give you access to data.byteBuffer which is a sequence type, so all those cool operations you can do with sequences also work, like doing a reduce { $0 &+ $1 } for a checksum.

Notes

In my previous edit, I used this method:

var buffer = Array<UInt8>(count: data.length, repeatedValue: 0x00)
data.getBytes(&buffer, length: data.length)
self.init(bytes: buffer, encoding: encoding)

The problem with this approach, is that I'm creating a copy of the information into a new array, thus, I'm duplicating the amount of bytes (specifically: encoding size * data.length)

Can
  • 8,502
  • 48
  • 57
4

Since the third version of Swift you can do the following:

let desiredString = NSString(data: yourData, encoding: String.Encoding.utf8.rawValue)

simialr to what Sunkas advised.

Dani Pralea
  • 4,545
  • 2
  • 31
  • 49
3
import Foundation
var string = NSString(data: NSData?, encoding: UInt)
mlask
  • 337
  • 1
  • 9
2

Another answer based on extensions (boy do I miss this in Java):

extension NSData {
    func toUtf8() -> String? {
        return String(data: self, encoding: NSUTF8StringEncoding)
    }
}

Then you can use it:

let data : NSData = getDataFromEpicServer()
let string : String? = data.toUtf8() 

Note that the string is optional, the initial NSData may be unconvertible to Utf8.

elcuco
  • 8,948
  • 9
  • 47
  • 69
0

Objective - C

NSData *myStringData = [@"My String" dataUsingEncoding:NSUTF8StringEncoding]; 
NSString *myStringFromData = [[NSString alloc] initWithData:myStringData encoding:NSUTF8StringEncoding];
NSLog(@"My string value: %@",myStringFromData);

Swift

//This your data containing the string
   let myStringData = "My String".dataUsingEncoding(NSUTF8StringEncoding)

   //Use this method to convert the data into String
   let myStringFromData =  String(data:myStringData!, encoding: NSUTF8StringEncoding)

   print("My string value:" + myStringFromData!)

http://objectivec2swift.blogspot.in/2016/03/coverting-nsdata-to-nsstring-or-convert.html

Tarun Seera
  • 4,212
  • 4
  • 27
  • 41