[TIMOB-8381] iOS: ENSURE_ARG_OR_NIL_AT_INDEX macro does not handle NSNull instance
GitHub Issue | n/a |
---|---|
Type | New Feature |
Priority | Low |
Status | Open |
Resolution | Unresolved |
Affected Version/s | Release 1.8.2 |
Fix Version/s | n/a |
Components | iOS |
Labels | n/a |
Reporter | Paul Mietz Egli |
Assignee | Unknown |
Created | 2012-03-13T10:54:34.000+0000 |
Updated | 2018-03-06T18:57:50.000+0000 |
Description
In my native module, I check for optional arguments to a method using the ENSURE_ARG_OR_NIL_AT_INDEX macro as follows:
- (id)myMethod:(id)args {
NSString * requiredArg;
NSString * optionalArg1;
NSNumber * optionalArg2;
ENSURE_ARG_AT_INDEX(requiredArg, args, 0, NSString);
ENSURE_ARG_OR_NIL_AT_INDEX(optionalArg1, args, 1, NSString);
ENSURE_ARG_OR_NIL_AT_INDEX(optionalArg2, args, 2, NSNumber);
/* remainder of method */
}
This code is throwing an error when optionalArg1 is null:
[ERROR] Invalid type passed to function. expected: NSString, was: NSNull in -[TDDatabaseProxy(Insertion) putRevision:] (TDDatabaseProxy+TDDatabaseProxy_Insertion.m:43)
Fix is to add a check for NSNull in the macro as shown on line 13 below:
#define ENSURE_ARG_OR_NIL_AT_INDEX(out,args,index,type) \
if (args==nil || args==[NSNull null]) \
{ \
out = nil; \
} \
else if ([args isKindOfClass:[NSArray class]]) { \
if ([args count]>index) {\
out = [args objectAtIndex:index]; \
}\
else { \
out = nil; \
} \
if (out && ![out isKindOfClass:[NSNull class]] && ![out isKindOfClass:[type class]]) { \
[self throwException:TiExceptionInvalidType subreason:[NSString stringWithFormat:@"expected: %@, was: %@",[type class],[out class]] location:CODELOCATION]; \
} \
} \
Here's a version of the macro that converts NSNull to nil instead, which more closely matches the intent of passing a JavaScript null to a module function. This is what I'm currently using for my projects.