Convert UTF-8 encoded NSData to NSString

前端 未结 7 794
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-22 08:43

I have UTF-8 encoded NSData from windows server and I want to convert it to NSString for iPhone. Since data contains characters (like a degree symb

相关标签:
7条回答
  • 2020-11-22 08:46

    Just to summarize, here's a complete answer, that worked for me.

    My problem was that when I used

    [NSString stringWithUTF8String:(char *)data.bytes];
    

    The string I got was unpredictable: Around 70% it did contain the expected value, but too often it resulted with Null or even worse: garbaged at the end of the string.

    After some digging I switched to

    [[NSString alloc] initWithBytes:(char *)data.bytes length:data.length encoding:NSUTF8StringEncoding];
    

    And got the expected result every time.

    0 讨论(0)
  • 2020-11-22 08:57

    If the data is not null-terminated, you should use -initWithData:encoding:

    NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
    

    If the data is null-terminated, you should instead use -stringWithUTF8String: to avoid the extra \0 at the end.

    NSString* newStr = [NSString stringWithUTF8String:[theData bytes]];
    

    (Note that if the input is not properly UTF-8-encoded, you will get nil.)


    Swift variant:

    let newStr = String(data: data, encoding: .utf8)
    // note that `newStr` is a `String?`, not a `String`.
    

    If the data is null-terminated, you could go though the safe way which is remove the that null character, or the unsafe way similar to the Objective-C version above.

    // safe way, provided data is \0-terminated
    let newStr1 = String(data: data.subdata(in: 0 ..< data.count - 1), encoding: .utf8)
    // unsafe way, provided data is \0-terminated
    let newStr2 = data.withUnsafeBytes(String.init(utf8String:))
    
    0 讨论(0)
  • I humbly submit a category to make this less annoying:

    @interface NSData (EasyUTF8)
    
    // Safely decode the bytes into a UTF8 string
    - (NSString *)asUTF8String;
    
    @end
    

    and

    @implementation NSData (EasyUTF8)
    
    - (NSString *)asUTF8String {
        return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];    
    }
    
    @end
    

    (Note that if you're not using ARC you'll need an autorelease there.)

    Now instead of the appallingly verbose:

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

    You can do:

    NSData *data = ...
    [data asUTF8String];
    
    0 讨论(0)
  • 2020-11-22 09:02

    You could call this method

    +(id)stringWithUTF8String:(const char *)bytes.
    
    0 讨论(0)
  • 2020-11-22 09:03

    With Swift 5, you can use String's init(data:encoding:) initializer in order to convert a Data instance into a String instance using UTF-8. init(data:encoding:) has the following declaration:

    init?(data: Data, encoding: String.Encoding)
    

    Returns a String initialized by converting given data into Unicode characters using a given encoding.

    The following Playground code shows how to use it:

    import Foundation
    
    let json = """
    {
    "firstName" : "John",
    "lastName" : "Doe"
    }
    """
    
    let data = json.data(using: String.Encoding.utf8)!
    
    let optionalString = String(data: data, encoding: String.Encoding.utf8)
    print(String(describing: optionalString))
    
    /*
     prints:
     Optional("{\n\"firstName\" : \"John\",\n\"lastName\" : \"Doe\"\n}")
    */
    
    0 讨论(0)
  • 2020-11-22 09:04

    Sometimes, the methods in the other answers don't work. In my case, I'm generating a signature with my RSA private key and the result is NSData. I found that this seems to work:

    Objective-C

    NSData *signature;
    NSString *signatureString = [signature base64EncodedStringWithOptions:0];
    

    Swift

    let signatureString = signature.base64EncodedStringWithOptions(nil)
    
    0 讨论(0)
提交回复
热议问题