在 UIPickerview xcode 上解析 JSON 值

Posted

技术标签:

【中文标题】在 UIPickerview xcode 上解析 JSON 值【英文标题】:Parsing JSON value on UIPickerview xcode 【发布时间】:2013-01-02 11:42:53 【问题描述】:

我有一个pickerview,我想通过它使用JSON 解析来显示值。我知道网站上的一些问题已经解决了解析和pickerview,但我的json文件结构略有不同。这是 json 文件的示例。

[

"model":"juice",
"id" :
  [
    
        "version": "version01"
    ,

    
        "version": "version02"
    

  ]
,
 
"model":"cream",
"id" :
[
  
      "version": "cream01"
  ,

  
      "version": "cream02"
  
]

]

还有我的 .m 文件

- (void)viewDidLoad
    
    [super viewDidLoad];

    NSURL * serverhost = [NSURL URLWithString:@"http://my.json"];

    NSError *error;

    NSData  * Data  = [NSData  dataWithContentsOfURL: serverhost];

    self.modelsArray= [NSJSONSerialization JSONObjectWithData:Data   options:NSJSONReadingAllowFragments error:&error];

    NSLog(@"%@", modelsArray);


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];


- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView

    return 2;


- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component

    if (component == departments)
        return [self.modelsArray count];
    return [self.versionsArray count];



#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView
         titleForRow:(NSInteger)row forComponent:(NSInteger)component

    if (component == departments)
          return [[self.modelsArray    objectAtIndex:row]objectForKey:@"model"];
    return [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"];


-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:    (NSInteger)component

    if (component == departments)
    
        NSString * selectedRow = [[self.modelsArray objectAtIndex: row]    valueForKey:@"version"];
        NSArray * array = [sybreDepts objectForKey:selectedRow];
        self.
    


@end

Basically when I select a model i.e juice or cream on the first column the second column should display its contents with key being 'versions' thus when juice is selected "version01" and "version02" should be displayed on the second column.

关于return [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"]; 行,我不相信它执行正确,因为我收到错误

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0xa18c450' . Any suggestions ? Thanks

【问题讨论】:

欢迎来到 ***。您的问题有几个问题:显示的 JSON 无效;会不会是version02 后面少了一个双引号? “但版本名称不是”是什么意思?它会崩溃吗?它不会编译吗?请更好地描述您期望发生的事情以及实际发生的事情。 return [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"]; 这条线是否曾被调用过?如果您使用键 model 检索元素,您只会得到一个字符串。但是您的代码希望找到一个带有 version 键的 JSON 对象。 嗨科多,谢谢。我已经更正了 json 文件,只是印刷错误。 Basically when I select a model i.e juice or cream on the first column the second column should display its contents with key being 'versions' thus when juice is selected "version01" and "version02" should be displayed on the second column.关于行返回 [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"];. 我不相信它被正确执行,因为我收到一个错误 *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[__NSCFString objectForKey:]:无法识别的选择器发送到实例0xa18c450' 现在这是您应该首先在问题中提供的重要信息。 【参考方案1】:

如果您很好地缩进您的 JSON 数据并查看它:

[
    
        "model": "juice",
        "id" : [
            
                "version": "version01"
            , 
            
                "version": "version02"
            
        ]
    ,
    ....

然后您会看到它具有以下结构(从外部元素到内部元素):

    一个数组 具有两个键的对象/字典:modelversionmodel 的字符串和键 id 的对象/字典 (仅适用于键 id)键 version 的字符串

所以如果你想访问第一个模型的第二个版本,你必须这样写:

NSArray* versionsArray = [[self.modelsArray objectAtIndex:modelRow] objectForKey:@"id"];
NSString* versionName = [[versionArray objectAtIndex: versionRow] objectForKey:@"version"];

在您的代码中,我看不到 self.versionArray 被赋值的位置。正如我在评论中指出的那样,以下行与 JSON 数据结构不匹配:

return [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"];

部分:

[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]

将返回一个NSString 实例。如果您随后调用 objectForKey:@"version",您将收到 unrecognized selector sent 错误。

更新:

更改后的代码可能如下所示:

.h 文件:

NSInteger modelRow;

.m 文件:

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView

    return 2;


- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

    if (component == departments)
        return [self.modelsArray count];

    NSArray* versionsArray = [[self.modelsArray objectAtIndex:modelRow] objectForKey:@"id"];
    return [versionsArray  count];


- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

    if (component == departments)
          return [[self.modelsArray objectAtIndex:row]objectForKey:@"model"];

    NSArray* versionsArray = [[self.modelsArray objectAtIndex:modelRow] objectForKey:@"id"];
    return [[versionsArray objectAtIndex:row] objectForKey:@"version"];


-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:    (NSInteger)component

    if (component == departments)
    
        modelRow = row;
        [pickerView reloadComponent:1];
    


@end

【讨论】:

versionRow如何获取它的值? 我没看懂,modelRow 和 versionRow 是什么?我如何向您展示我的代码,因为重新编辑问题会很好? modelRowversionRow 是第一个和第二个纺车的行号。根据您放置代码的位置,它只是函数的 row 参数。如果为左旋转轮调用 pickerView:didSelectRow:inComponent:,您可能需要将 row 参数保存为 modelRow(实例变量)。然后,如果为右转轮调用 pickerView:titleForRow:forComponent:,则 modelRowmodelRow 并且 rowversionRow 啊,我明白了,我最初在我的 .h 文件中定义了 #define 模型 0 和 #define 版本 1。我的代码仍然有错误,我想向您展示我的代码,但重新编辑整个问题是错误的。你有什么建议? 您好,您收到消息了吗?

以上是关于在 UIPickerview xcode 上解析 JSON 值的主要内容,如果未能解决你的问题,请参考以下文章

UIPickerView 上显示问号,而不是 Xcode 10 上的 Realm 数据

UIPickerview 多个文本字段 Xcode

xcode iphone UIPickerView

Swift/Xcode - AKPickerView/UIPickerView - 致命错误:索引超出范围

如何解决问题 UIPickerView 致命错误:索引超出范围 [IOS Swift 5.1 Xcode 11.2]

保存 UIPickerView 数据以进行解析