Проблема преобразования NSData в NString - PullRequest
5 голосов
/ 12 сентября 2009

Я получаю HTML-файл как NSData, и мне нужно извлечь некоторые его части. Для этого мне нужно преобразовать его в NSString с кодировкой UTF8. Дело в том, что это преобразование завершается неудачей, возможно, потому, что NSData содержит байты, которые недопустимы для UTF8. Я пытался получить байтовый массив данных и просмотреть его, но каждый раз, когда я сталкиваюсь с не ASCII-символом (например, ивритом), я получаю jibrish.

Помощь будет оценена.

UPDATE:

Гордону - NSData, сгенерированный так:

    NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];

Когда я говорю, что преобразование не удается, я имею в виду, что

[[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding]

возвращает ноль

Эд. Вот мой код (я получил массив байтов из NSData, нашел то, что мне нужно, и сконструировал еще один массив байтов из этого - превратил его в NSData, а затем попытался преобразовать в NSString ... звучит довольно сложно ...)

-(NSString *)UTF8StringFromData:(NSData *)theData{
Byte *arr = [theData bytes];
NSUInteger begin1 = [self findIndexOf:@"<li>" bArr:arr size:[theData length]]+4;
NSUInteger end1 = [self findIndexOf:@"</li></ol>" bArr:arr size:[theData length]];
Byte *arr1 = (Byte *)malloc(sizeof(Byte)*((end1-begin1+1)));
NSLog(@"%d %d",begin1, end1);
int j = 0;
for (int i = begin1; i < end1; i++){
    arr1[j] = arr[i];
    j++;
}
arr1[j]='\0';
NSData *temp = [NSData dataWithBytes:arr1 length:j];

return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];

}

Ответы [ 4 ]

6 голосов
/ 08 июня 2010

Я знаю, что это старая тема, но она возникла, когда я искал решение сегодня. Я решил это сейчас, поэтому я просто публикую это для тех, кто может столкнуться с этой страницей в поисках решения.

Вот что я делаю в асинхронном запросе:

Сначала я сохраняю имя кодировки текста в подключении: didReceiveResponse, используя

encodingName = [[NSString alloc] initWithString:[response textEncodingName]];

Затем в моем методе подключения DidFinishLoading я использовал

NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef) encodingName));
NSString *payloadAsString = [[NSString alloc] initWithData:receivedData encoding:encoding];
0 голосов
/ 12 сентября 2009

Вы проверили charset = в заголовках HTTP и / или в самом документе? Наиболее вероятной причиной неудачного преобразования является то, что байты не представляют допустимую строку UTF-8.

0 голосов
/ 13 сентября 2009

Я не уверен, что если вы в курсе, вам на самом деле не нужно копировать массив в другой массив, прежде чем помещать его в новый объект NSData.

-(NSString *)UTF8StringFromData:(NSData *)theData {
  Byte *arr = [theData bytes];
  NSUInteger begin1 = [self findIndexOf:@"<li>" bArr:arr size:[theData length]]+4;
  NSUInteger end1 = [self findIndexOf:@"</li></ol>" bArr:arr size:[theData length]];
  Byte *arr1 = arr + begin1;
  NSData *temp = [NSData dataWithBytes:arr1 length:end1 - begin1];
  return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];
}

Что касается вашей конкретной проблемы, я бы попытался просмотреть данные вручную с помощью отладчика. Поставьте точку останова после того, как у вас есть массив (arr1). Когда вы нажмете на нее, откройте консоль GDB и попробуйте это:

print (char *)arr1

С вашим кодом он должен распечатать строку, которую вы пытаетесь получить. (С кодом, который я дал выше, он не остановится после . Он просто продолжит работать).

Если результат не соответствует вашим ожиданиям, значит, что-то не так с данными или, возможно, с вашими границами begin1 и end1.

0 голосов
/ 12 сентября 2009

Гордону - NSData, сгенерированный так:

    NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];

Когда я говорю, что преобразование не удается, я имею в виду, что

[[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding]

возвращает ноль

Эд. Вот мой код (я получил байтовый массив из NSData, нашел то, что мне нужно, и сконструировал еще один байтовый массив из этого - превратил его в NSData, а затем попытался преобразовать в NSString ... звучит довольно сложно ...)

-(NSString *)UTF8StringFromData:(NSData *)theData{
Byte *arr = [theData bytes];
NSUInteger begin1 = [self findIndexOf:@"<li>" bArr:arr size:[theData length]]+4;
NSUInteger end1 = [self findIndexOf:@"</li></ol>" bArr:arr size:[theData length]];
Byte *arr1 = (Byte *)malloc(sizeof(Byte)*((end1-begin1+1)));
NSLog(@"%d %d",begin1, end1);
int j = 0;
for (int i = begin1; i < end1; i++){
    arr1[j] = arr[i];
    j++;
}
arr1[j]='\0';
NSData *temp = [NSData dataWithBytes:arr1 length:j];

return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];

}

...