Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[ios] predicateWithMGLJSONObject can return Invalid filter value: filter property must be a string #14805

Closed
mfazekas opened this issue May 30, 2019 · 5 comments
Labels
iOS Mapbox Maps SDK for iOS

Comments

@mfazekas
Copy link

Using predicateWithMGLJSONObject can return Invalid filter value: filter property must be a string for a valid expression because of NSPredicate conversion.

Steps to reproduce

        statesLayer.predicate = [NSPredicate predicateWithMGLJSONObject: @[
                                                                           @"all",
                                                                           @[@"==", @"$type", @"Point"],
                                                                           @[@"in", @"type", @"Blue Project", @"WFW Project"]
                                                                           ]
                                 ];

Expected behavior

Expected to work.

Actual behavior

Raises exception:

'NSInvalidArgumentException', reason: 'Invalid filter value: filter property must be a string'
*** First throw call stack:
(
	0   CoreFoundation                      0x0000000107d5d6fb __exceptionPreprocess + 331
	1   libobjc.A.dylib                     0x000000010884cac5 objc_exception_throw + 48
	2   CoreFoundation                      0x0000000107d5d555 +[NSException raise:format:] + 197
	3   Mapbox                              0x0000000103c808f3 -[NSPredicate(MGLPrivateAdditions) mgl_filter] + 387
	4   Mapbox                              0x0000000103c9ac70 -[MGLFillStyleLayer setPredicate:] + 928

Configuration

Mapbox SDK versions: 316584f - 5.1.0.alpha1
iOS/macOS versions: 12.2/10.14.4
Device/simulator models: iPhone X
Xcode version: 10.2.1

@mfazekas
Copy link
Author

mfazekas commented May 30, 2019

See https://github.com/react-native-mapbox-gl/maps/issues/70

The issue seems to be that the following JSON

[
    'all',
   ['==', '$type', 'Point'],
   ['in', 'type', 'Blue Project', 'WFW Project']
]

Becomes the following NSPredicate for NSPredicate predicateWithMGLJSONObject

"$type" == "Point" AND MGL_FUNCTION("in", "type", "Blue Project", "WFW Project") == 1

And for that predicate.mgl_jsonExpressionObject

[
     'all',
     ['==', '$type', 'Point'],
     ['==', ['in', 'type', 'Blue Project', 'WFW Project'], 1]
]

And it sounds like the first argument to == is expected to be a string not an array.

Seems to be coming from

ParseResult convertLegacyComparisonFilter(const Convertible& values, Error& error, optional<std::string> opOverride = {}) {
optional<std::string> op = opOverride ? opOverride : toString(arrayMember(values, 0));
optional<std::string> property = toString(arrayMember(values, 1));
if (!property) {
error.message = "filter property must be a string";
return {};
} else if (*property == "$type") {
return createExpression("filter-type-" + *op, convertLiteralArray(values, error, 2), error);
} else if (*property == "$id") {
return createExpression("filter-id-" + *op, convertLiteralArray(values, error, 2), error);
} else {
return createExpression("filter-" + *op, convertLiteralArray(values, error, 1), error);
}
}
and
*op == "==" ||
*op == "<" ||
*op == ">" ||
*op == "<=" ||
*op == ">=" ? convertLegacyComparisonFilter(values, error) :

@julianrex
Copy link
Contributor

Thanks for the detailed report @mfazekas!

@1ec5
Copy link
Contributor

1ec5 commented Jun 6, 2019

all and in are part of the filter syntax in the style specification. Filters are deprecated and are no longer supported in the native SDKs. You should use an expression instead.

@1ec5 1ec5 closed this as completed Jun 6, 2019
@mfazekas
Copy link
Author

mfazekas commented Jun 7, 2019

@1ec5 I'm a bit confused. The expression docs you're referring to shows all as a valid expression.

kép

@mfazekas
Copy link
Author

mfazekas commented Jun 7, 2019

@1ec5 nevermind if i convert "in" to expression from legacy filter as well it works fine:

@[
       @"all",
        @[@"==", @[@"geometry-type"], @"Point"],
        @[@"match",
                 @[@"get", @"type"],
                 @[@"Blue Project", @"WFW Project"], @YES,
                 @NO]
           ]

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS Mapbox Maps SDK for iOS
Projects
None yet
Development

No branches or pull requests

3 participants