Jak przekonwertować wartość NSString na NSData?


Odpowiedzi:


1419
NSString* str = @"teststring";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];

Jakie są zalety i wady używania UTF-8 w porównaniu do czegoś wyższego, takiego jak UTF-16 lub UTF-32?
Albert Renshaw

4
NSData nie dba o to, czy jest to UTF-8, UTF-16 czy UTF-32. Istnieją dwa problemy: jeden, UTF-16 i UTF-32 muszą mieć odpowiednią kolejność bajtów. Po drugie, ktokolwiek konwertuje go z powrotem na NSString *, musi znać kodowanie i często przyjmuje kodowanie UTF-8. Ogólnie rzecz biorąc, UTF-8 najprawdopodobniej będzie obsługiwany poprawnie.
gnasher729

1
@bendytree faktycznie nie, nie robi, -dataUsingEncoding: zwróci ciąg nie zakończony znakiem null, który jest tym, czego wymaga stringWithUTF8String: jesteś zobowiązany do odczytu pamięci, której nie chcesz. To, co konwertuje to z powrotem to: -initWithData: kodowanie :.
Psycho

1
@Albert Renshaw obecnie (bez gwarancji, że tak pozostanie) NSStringużywa UTF-16 wewnętrznie, więc może wystąpić niewielki wzrost wydajności, ponieważ nie musi on wykonywać konwersji UTF-16 <-> UTF-8. Osobiście wolimy (jak sugeruje @ gnasher729) solidność od wydajności i używamy UTF-8 wszędzie.
Some Developer

66
NSString *str = @"helowrld";
// This converts the string to an NSData object
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];

możesz skorzystać z tego linku


3
Jedno rozwiązanie liniowe:NSData *data = [@"helowrld" dataUsingEncoding:NSUTF8StringEncoding];
Raptor

32

Zrobić:

NSData *data = [yourString dataUsingEncoding:NSUTF8StringEncoding];

następnie możesz kontynuować NSJSONSerialization:JSONObjectWithData.


Korekta odpowiedzi dotyczącej terminatora NULL

Po komentarzach, oficjalnej dokumentacji i weryfikacjach odpowiedź została zaktualizowana w odniesieniu do usunięcia domniemanego terminatora NULL:

  1. Zgodnie z dokumentacją dataUsingEncoding ::

    Zwracana wartość

    Wynik wywołania dataUsingEncoding:allowLossyConversion:z NIE jako drugim argumentem

  2. Zgodnie z dokumentacją getCString: maxLength: encoding: i cStringUsingEncoding ::

    zwróć uwagę, że dane zwracane przez dataUsingEncoding:allowLossyConversion:nie są ścisłym ciągiem C, ponieważ nie ma terminatora NULL


14
To jest źle! Proszę zobaczyć mój post tutaj: stackoverflow.com/q/14087094/192819
jpswain 30.12

4
Tak. dataUsingEncoding:nie zwraca danych zakończonych zerem. Tylko UTF8Stringinne metody zwracające ciąg C zwracają ciąg zakończony znakiem null.
Peter Hosey

@PeterHosey czy masz na to jakieś źródło? Trudno mi to znaleźć w jakichkolwiek dokumentach.
shortstuffsushi

1
Dzięki @PeterHosey, docs jesteś połączony tam nie wyraźnie stwierdzić brak zakończenia null - (note that the data returned by dataUsingEncoding:allowLossyConversion: is not a strict C-string since it does not have a NULL terminator). Musiałem wcześniej to przegapić. Ale na pewno coś napiszę w przyszłości.
shortstuffsushi,

1
(Dla każdego, kto się zastanawia: cytat shortstuffsushi jest poniżej cStringUsingEncoding:. dataUsingEncoding:
Patrzyłem

20

W przypadku przyjazdu Swift Developer,

przekonwertować z NSString / String na NSData

var _nsdata = _nsstring.dataUsingEncoding(NSUTF8StringEncoding)

18

Cel C:

NSString *str = @"test string";
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:str];
NSString *thatStr = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Szybki:

let str = "test string"
let data = NSKeyedArchiver.archivedData(withRootObject: str)
let thatStr = NSKeyedUnarchiver.unarchiveObject(with: data) as! String

Prawdopodobnie wymaga dużego procesora w porównaniu z innymi metodami, ale jest bardzo przydatny, jeśli uzyskujesz dostęp do systemu plików w celu zachowania trwałości
Stephen J

10

Po pierwsze, powinieneś użyć dataUsingEncoding:zamiast przejść UTF8String. Używasz tylko UTF8Stringwtedy, gdy potrzebujesz Cłańcucha w tym kodowaniu.

Następnie, po UTF-16prostu podaj NSUnicodeStringEncodingzamiast NSUTF8StringEncodingw dataUsingEncoding:wiadomości.


7

W przypadku Swift 3 przeważnie konwertujesz z Stringna Data.

let myString = "test"
let myData = myString.data(using: .utf8)
print(myData) // Optional(Data)

6
NSString *str = @"hello";
NSData *data = [NSData dataWithBytes:str.UTF8String length:str.length];

5
Ta odpowiedź jest niepoprawna, gdy strzawiera punkty kodu większe niż 127. Jest tak, ponieważ str.lengthpodaje liczbę znaków Unicode, a nie liczbę bajtów. Na przykład, jeśli strjest @"にほんご", str.lengthdaje 4, podczas gdy str.UTF8Stringfaktycznie zawiera 12 bajtów. Nawet jeśli zastąpić str.lengthprzez strlen(str.UTF8String), to nadal będzie źle dla przypadku, gdy strzawiera znak NULL, takich jak @"にほ\0んご".
Pang

Tak utworzony obiekt NSData zgłasza wyjątek podczas używania z [NSJSONSerialization JSONObjectWithData: opcje danych: NSJSONReadingMutableLeaves error: & error];
Adobels

2

Cel C:

NSString do NSData:

NSString* str= @"string";
NSData* data=[str dataUsingEncoding:NSUTF8StringEncoding];

NSData do NSString:

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

Szybki:

Ciąg do danych:

var testString = "string"
var somedata = testString.data(using: String.Encoding.utf8)

Dane do ciągu:

var backToString = String(data: somedata!, encoding: String.Encoding.utf8) as String!

1
NSString *str = @"Banana";
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:true];

0

Cel C

NSString *str = @"Hello World";
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];

Szybki

let str = "Hello World"
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: false)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.