Лучшее шахматное учебное руководство по программированию для новичков в GameDev. Очень легко понять, в то время как это очень вдается в подробности.
проверяли ли вы charset = в заголовках HTTP и / или в самом документе? Наиболее вероятная причина сбоя преобразования заключается в том, что байты не представляют допустимую строку UTF-8.
Гордону - NSData сгенерированы следующим образом:
NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
Когда я говорю, что преобразование не выполнено, я имею в виду, что
[[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding]
возвращает nil
Эду - Вот мой код (я получил массив байтов из 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];
}
Я не уверен, знаете ли вы, что вам действительно не нужно копировать массив в другой массив, прежде чем помещать его в новый объект 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
границы.
Я знаю, что это старая тема, но она всплыла, когда я искал решение сегодня. Теперь я решил эту проблему, поэтому я просто размещаю ее для других, кто может наткнуться на эту страницу в поисках решения.
Вот что я делаю в асинхронном запросе:
Сначала я сохраняю имя текстовой кодировки в connection: didReceiveResponse using
encodingName = [[NSString alloc] initWithString:[response textEncodingName]];
Затем позже в методе connectionDidFinishLoading я использовал
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef) encodingName));
NSString *payloadAsString = [[NSString alloc] initWithData:receivedData encoding:encoding];