2015-03-27 2 views
0

Я работаю над приложением, которое будет анализировать данные из Rest API. Поскольку я не делал этого раньше, мне было интересно, будут ли NSScanner или NSRange работать для этого. Вот пример использования NSScanner для таких целей. Это небольшая строка, поэтому она не требует большого количества кода, поэтому она показалась быстрой и грязной. Есть ли более простой и быстрый способ сделать это?Как разобрать ответ JSON от Rest API

- (void)GetAliasName:(NSString *)cno selector:(NSString*)selectorName completionHandler:(void (^)(NSDictionary *, NSError *))handler 

{ 

NSMutableDictionary *d = [[NSMutableDictionary alloc] init]; 

[d setValue:interface forKey:@"interface"]; 

[d setValue:@"GetAlias" forKey:@"method"]; 

NSMutableDictionary *p = [[NSMutableDictionary alloc] init]; 

cno = [[NSUserDefaults standardUserDefaults] objectForKey:@"cno"]; 

[p setValue:cno forKey:@"cno"]; 

[p setValue:selectorName forKey:@"selector"]; 

[d setValue:p forKey:@"parameters"]; 

NSData *data = [NSJSONSerialization dataWithJSONObject:d options:0 error:nil]; 

[self load:data completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 

    NSLog(@"done"); 

    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    NSLog(@"GetAlias RAW response = %@", s); 

    if (apiConditions) 
    { 
     dispatch_async(dispatch_get_main_queue(), 
         ^{ 
          [hud hide:YES]; 
          [MBProgressHUD hideHUDForView:self.view animated:YES]; 
          UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"No network connection or no data found" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
          [alert show]; 
          NSLog(@"data is NIL"); 
         }); 


    } 
    else 
    { 
     NSDictionary *d = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
     handler(d, error); 

      //scans for aliasname 
      NSString *match = @"AliasName\": \""; 
      NSString *preTel; 
      NSString *postTel; 

      NSScanner *scanner = [NSScanner scannerWithString:s]; 
      [scanner scanUpToString:match intoString:&preTel]; 

      [scanner scanString:match intoString:nil]; 
      postTel = [s substringFromIndex:scanner.scanLocation]; 


      //removes newlines, characters, and whitespaces from aliasname 
      NSCharacterSet *trim = [NSCharacterSet characterSetWithCharactersInString:@"}]\""]; 
      postTel = [[postTel componentsSeparatedByCharactersInSet: trim] componentsJoinedByString: @""]; 
      postTel = [[postTel componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString: @""]; 


      NSLog(@"postTel: %@", postTel); 
      NSString *docno = [[NSUserDefaults standardUserDefaults] objectForKey:@"docno"]; 

      //if docno is filled in, look up TR by docno 
      if ([docno isEqual: @""]) 
      { 

      [self GetTR:(NSString*)postTel customStatus:customStatus completionhandler:^(NSDictionary *dictionary, NSError *error) { 
       nil; 
      }]; 

} 
}]; 
} 
+0

Почему вы используете 'NSScanner? У вас есть словарь 'd', просто получите доступ к значениям по подписчикам. Добавление NSLog словаря поможет, просто добавьте его в вопрос. – zaph

+0

Ну это не кажется гораздо более эффективным со словарем, как он будет возвращать несколько дополнительных символов, а также IE- ( { Псевдоимя = АСМАП; } ) –

+1

'NSData * данные = [NSJSONSerialization dataWithJSONObject: D Параметры: 0 error: nil]; 'уже возвращает словарь. Для «данных действительно был внутри словаря, внутри массива, внутри другого словаря решение: s d [@« outerKey »] [arrayIndex] [@" innerKey "]", заменяя внешниеKey, arrayIndex и innerKey соответствующими ключами и индексами. Что касается эффективности: даже не рассматривайте это, рассмотрите наиболее прямолинейное решение. – zaph

ответ

2

Существует NSJSONSerialization, который построен для этого.

Используйте его следующим образом:

NSError *error = nil; 
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 
NSString *aliasName = dictionary[@"AliasName"]; 

Редактировать

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

+0

@ Zaph, да, я заметил это и сделал редактирование. Просто пропустил первую строчку в другой части. –

+0

Спасибо, я обнаружил, что данные были фактически в словаре, внутри массива, в другом словаре. –