Я уже сталкивался с проблемами кодирования URL-адресов, поэтому в итоге я написал на NSString категорию для правильного кодирования URL-адресов:
- (NSString *) URLEncodedString {
NSMutableString * output = [NSMutableString string];
const char * source = [self UTF8String];
int sourceLen = strlen(source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = (const unsigned char)source[i];
if (thisChar == ' '){
[output appendString:@"+"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
return output;
}
- (NSString *) URLDecodedString {
NSString * spacedDecoded = [self stringByReplacingOccurrencesOfString:@"+" withString:@" "];
return [spacedDecoded stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
Об этом есть пара замечаний:
- Это будет кодировать пробелы как "+"
- Это кодирует все, кроме az (верхний и нижний регистр), чисел, периода, дефиса, подчеркивания и тильды
Это будет правильнокодировать символы Юникода как несколько октетов.Например, я могу сделать:
NSString * enc = [@"http://example.com/?data=÷¡¿" URLEncodedString];
NSLog(@"%@", enc);
NSLog(@"%@", [enc URLDecodedString]);
, который будет правильно регистрировать:
Testing.m:65 main() http%3A%2F%2Fexample.com%2F%3Fdata%3D%C3%B7%C2%A1%C2%BF
Testing.m:66 main() http://example.com/?data=÷¡¿
РЕДАКТИРОВАТЬ Я скопировал и вставил его впустой проект, например:
NSString * string = @"00000000-0000-1000-8000-0013775CE6D2";
NSString *result = (NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR("'\"?=&+<>;:-"), kCFStringEncodingUTF8);
NSLog(@"encode? %@", result);
result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"decode? %@", result);
NSLog(@"equal? %d", [string isEqual:result]);
И он записывает:
Testing[62541:a0f] encode? 00000000%2D0000%2D1000%2D8000%2D0013775CE6D2
Testing[62541:a0f] decode? 00000000-0000-1000-8000-0013775CE6D2
Testing[62541:a0f] equal? 1
Причина, по которой ваш код не работает, заключается в том, что вы записываете строку в качестве форматастрока , что означает, что он видит материал %2
и пытается заменить его другими вещами.Обратите внимание:
NSString * string = @"00000000-0000-1000-8000-0013775CE6D2";
NSString *result = (NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR("'\"?=&+<>;:-"), kCFStringEncodingUTF8);
NSLog(@"%@", result);
NSLog(result);
Журналы:
Testing[62585:a0f] 00000000%2D0000%2D1000%2D8000%2D0013775CE6D2
Testing[62585:a0f] 00000000879923200001897296640100041968968000 00013775CE6D2
Таким образом, строка корректно кодируется, но вы просто регистрируете ее неправильно.