错误:无法使用非字符串的内容执行子字符串操作

时间:2017-11-16 10:14:03

标签: ios objective-c nsstring

这个问题已被多次询问,我已经完成了每一个解决方案,也试图实施,但没有一个适合我。

问题:使用Can't do a substring operation with something that isn't a string过滤NSArray时出现此错误:NSPredicate

编码资料:通过这种方式,我正在尝试过滤我的数组

NSArray *array = [[NSArray alloc]initWithArray:dataArray];

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH[c] %@", searchText];

allProductData = [[array filteredArrayUsingPredicate:resultPredicate]mutableCopy]; //Error is here

现在有两个数组用于第一个数组,相同的代码不适用于第二个数组。

数组1:适用于此阵列。

(
        {
        "_id" = 59483833710f853221c90a92;
        attributes =         (
                        {
                key = Atributos;
                value = "-";
            }
        );
        name = "Ades Soya Bebida Chocolate 946 Ml";
        price = "-";
        uri = "http://res.cloudinary.com/cloudimp/image/upload/u3kgmm8bx5lsmmacbnrl.jpg";
    },
        {
        "_id" = 5948383f853221c90a94;
        attributes =         (
        );
        name = "Ades Soya Bebida Chocolate 200 Ml";
        price = "";
        uri = "http://res.cloudinary.com/cloudimp/image/upload/hhafrnwocqoamhhievoy.jpg";
    }

) 

过滤键: name = "Ades Soya Bebida Chocolate 946 Ml";

数组2:过滤器不适用于此阵列。

(
        {
        image = "http://images.qliktag.com/image/upload/w3tb9dutynou1hlooexn.gif";
        name = Abuelita;
        products =         (
                        {
                "_id" = 594c030f124244325;
                attributes =                 (
                );
                name = "Abuelita chocolate granulado";
                price = "";
                uri = "http://images.qliktag.com/image/upload/iiqfuiilstvksdycnfbc.jpg";
            },
                        {
                "_id" = 5931c73303f737086;
                attributes =                 (
                );
                name = "ABUELITA Chocolate";
                price = "";
                uri = "<null>";
            },

             { //Crashing app for this while reading this structure.
                "_id" = 5931c73303f737086;   
                attributes =                 (
                );
                name = (
                             {
                                language = @"en"
                                value = "SOYA"
                             },
                             {
                                language = @"de"
                                value = "SOYA Bebida"
                             }
                          );
                price = "";
                uri = "<null>";
            }
        );
    }

注意:两个数组name的值都不同。

最后我要过滤name

name1 = "Ades Soya Bebida Chocolate 946 Ml"

name2 = Abuelita; //Crashing app for this while filtering.

数组正在动态变化,看起来与此类似......

example-1:应用程序崩溃,出现此错误:无法对不是字符串的内容执行子字符串操作。

          ContactName[0] "ABC"
          ContactName[1] = XYZ
          ContactName[2] = (
                             {
                                language = @"en"
                                value = "PQR"
                             },
                             {
                                language = @"de"
                                value = "QWERTY"
                             }
                          )

示例2:应用程序正常运行

          ContactName[0] = "ABC"
          ContactName[1] = "XYZ"
          ContactName[2] = "PQR"

那么,我应该如何过滤这样的数组... ???

1 个答案:

答案 0 :(得分:0)

我建议-[NSPredicate predicateWithBlock:]

测试product[@"name"]的类型。如果类型为NSString,请使用-[NSString hasPrefix:]。如果类型为NSArray,则找到等于NSLocale.currentLocale.languageCode的语言,然后比较,然后在值上使用-[NSString hasPrefix:]

- (void)testBeginsWithSearchText {
    NSArray<NSDictionary *> *data =
    @[@{@"image": @"http://images.qliktag.com/image/upload/w3tb9dutynou1hlooexn.gif",
        @"name": @"Abuelita",
        @"products": @[@{@"_id": @"594c030f124244325",
                         @"attributes": @[],
                         @"name": @"Abuelita chocolate granulado",
                         @"price": @"",
                         @"uri": @"http://images.qliktag.com/image/upload/iiqfuiilstvksdycnfbc.jpg"},
                       @{@"_id": @"5931c73303f737086",
                         @"attributes": @[],
                         @"name": @"ABUELITA Chocolate",
                         @"price": @"",
                         @"uri": @"<null>"},
                       @{@"_id": @"5931c73303f737086",
                         @"attributes": @[],
                         @"name": @[@{@"language": @"en",
                                      @"value": @"SOYA"},
                                    @{@"language": @"de",
                                      @"value": @"SOYA Bebida"}],
                         @"price": @"",
                         @"uri": @"<null>"}]}];

    NSString *searchText = @"SOYA";

    id beginsWithSearchText = [NSPredicate predicateWithBlock:^BOOL(NSDictionary *product, NSDictionary *bindings) {
        if ([product[@"name"] isKindOfClass:[NSString class]]) {
            return [product[@"name"] hasPrefix:searchText];
        } else if ([product[@"name"] isKindOfClass:[NSArray class]]) {
            NSUInteger index = [product[@"name"] indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
                return [obj[@"language"] isEqualToString:NSLocale.currentLocale.languageCode];
            }];

            return index != NSNotFound && [product[@"name"][index][@"value"] hasPrefix:searchText];
        } else {
            return NO;
        }
    }];

    NSArray *result = [data.firstObject[@"products"] filteredArrayUsingPredicate:beginsWithSearchText];

    XCTAssertEqual(result.count, 1);
    XCTAssertEqualObjects(result.firstObject[@"_id"], @"5931c73303f737086");
}