[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.
#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 isKindOfClass:[NSNull class]]) { \ out = nil;\ }\ if (out && ![out isKindOfClass:[type class]]) { \ [self throwException:TiExceptionInvalidType subreason:[NSString stringWithFormat:@"expected: %@, was: %@",[type class],[out class]] location:CODELOCATION]; \ } \ } \