строка кодирования для URL - PullRequest
1 голос
/ 23 июня 2010

Мне нужно отправить данные на страницу php из приложения Iphone, поэтому мне нужно правильно закодировать параметры, преобразовав специальные символы ...

В частности, мне нужно отправить UDID iphone.

Я нашел много справок в сети для кодирования String для передачи в качестве параметра, но я получил странную ошибку.

Я использую эту функцию:

- (NSString *)URLEncodeString:(NSString *)string { 

NSString *result =
   (NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
    (CFStringRef)string, NULL, CFSTR("'\"?=&+<>;:-"), kCFStringEncodingUTF8);

return [result autorelease];}

кажется правильным, но когда я его использую, результат не тот, на который я рассчитываю.

Это код:

UIDevice *device = [UIDevice currentDevice];
NSString *uniqueIdentifier = [device uniqueIdentifier];

NSLog(uniqueIdentifier);
NSLog([self URLEncodeString:uniqueIdentifier]);

, и это журнал, сгенерированный, когда янажмите на этот код:

2010-06-23 21:58:51.671 provaNavigation[2343:20b] 00000000-0000-1000-8000-0013775CE6D2
2010-06-23 21:58:51.672 provaNavigation[2343:20b] 0000000010003900009080176010001273086780001283520013775CE6D2

и снова:

2010-06-23 21:59:25.614 provaNavigation[2343:20b] 00000000-0000-1000-8000-0013775CE6D2
2010-06-23 21:59:25.615 provaNavigation[2343:20b] 000000001000390000908192801000-18000912258750013775CE6D2

и еще раз:

2010-06-23 21:59:40.848 provaNavigation[2343:20b] 00000000-0000-1000-8000-0013775CE6D2
2010-06-23 21:59:40.849 provaNavigation[2343:20b] 000000001000390000908866081000-18000912239630013775CE6D2

и снова ...

Я получаюкаждый раз новое значение и никогда не исправляйте правильное число%.

1 Ответ

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

Я уже сталкивался с проблемами кодирования 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];
}

Об этом есть пара замечаний:

  1. Это будет кодировать пробелы как "+"
  2. Это кодирует все, кроме az (верхний и нижний регистр), чисел, периода, дефиса, подчеркивания и тильды
  3. Это будет правильнокодировать символы Юникода как несколько октетов.Например, я могу сделать:

    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

Таким образом, строка корректно кодируется, но вы просто регистрируете ее неправильно.

...