{ "id": "87825", "key": "TIMOB-8381", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": null, "resolutiondate": null, "created": "2012-03-13T10:54:34.000+0000", "priority": { "name": "Low", "id": "4" }, "labels": [], "versions": [ { "id": "13070", "description": "Release 1.8 Service Pack 2", "name": "Release 1.8.2", "archived": true, "released": true, "releaseDate": "2012-02-29" } ], "issuelinks": [], "assignee": null, "updated": "2018-03-06T18:57:50.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "In my native module, I check for optional arguments to a method using the ENSURE_ARG_OR_NIL_AT_INDEX macro as follows:\r\n\r\n{code:none}\r\n- (id)myMethod:(id)args {\r\n NSString * requiredArg;\r\n NSString * optionalArg1;\r\n NSNumber * optionalArg2;\r\n \r\n ENSURE_ARG_AT_INDEX(requiredArg, args, 0, NSString);\r\n ENSURE_ARG_OR_NIL_AT_INDEX(optionalArg1, args, 1, NSString);\r\n ENSURE_ARG_OR_NIL_AT_INDEX(optionalArg2, args, 2, NSNumber);\r\n \r\n /* remainder of method */\r\n}\r\n{code}\r\n\r\nThis code is throwing an error when optionalArg1 is null:\r\n\r\n{code:none}\r\n[ERROR] Invalid type passed to function. expected: NSString, was: NSNull in -[TDDatabaseProxy(Insertion) putRevision:] (TDDatabaseProxy+TDDatabaseProxy_Insertion.m:43)\r\n{code}\r\n\r\nFix is to add a check for NSNull in the macro as shown on line 13 below:\r\n\r\n{code:none}\r\n#define ENSURE_ARG_OR_NIL_AT_INDEX(out,args,index,type) \\\r\nif (args==nil || args==[NSNull null]) \\\r\n{ \\\r\nout = nil; \\\r\n} \\\r\nelse if ([args isKindOfClass:[NSArray class]]) { \\\r\nif ([args count]>index) {\\\r\nout = [args objectAtIndex:index]; \\\r\n}\\\r\nelse { \\\r\nout = nil; \\\r\n} \\\r\nif (out && ![out isKindOfClass:[NSNull class]] && ![out isKindOfClass:[type class]]) { \\\r\n[self throwException:TiExceptionInvalidType subreason:[NSString stringWithFormat:@\"expected: %@, was: %@\",[type class],[out class]] location:CODELOCATION]; \\\r\n} \\\r\n} \\\r\n{code}", "attachment": [], "flagged": false, "summary": "iOS: ENSURE_ARG_OR_NIL_AT_INDEX macro does not handle NSNull instance", "creator": { "name": "pegli", "key": "pegli", "displayName": "Paul Mietz Egli", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "pegli", "key": "pegli", "displayName": "Paul Mietz Egli", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "iOS SDK version 1.8.2", "comment": { "comments": [ { "id": "191126", "author": { "name": "pegli", "key": "pegli", "displayName": "Paul Mietz Egli", "active": true, "timeZone": "America/Los_Angeles" }, "body": "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.\r\n\r\n{code:none}\r\n#define ENSURE_ARG_OR_NIL_AT_INDEX(out,args,index,type) \\\r\nif (args==nil || args==[NSNull null]) \\\r\n{ \\\r\nout = nil; \\\r\n} \\\r\nelse if ([args isKindOfClass:[NSArray class]]) { \\\r\nif ([args count]>index) {\\\r\nout = [args objectAtIndex:index]; \\\r\n}\\\r\nelse { \\\r\nout = nil; \\\r\n} \\\r\nif ([out isKindOfClass:[NSNull class]]) { \\\r\nout = nil;\\\r\n}\\\r\nif (out && ![out isKindOfClass:[type class]]) { \\\r\n[self throwException:TiExceptionInvalidType subreason:[NSString stringWithFormat:@\"expected: %@, was: %@\",[type class],[out class]] location:CODELOCATION]; \\\r\n} \\\r\n} \\\r\n{code}\r\n", "updateAuthor": { "name": "pegli", "key": "pegli", "displayName": "Paul Mietz Egli", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-04-16T10:32:59.000+0000", "updated": "2012-04-16T10:32:59.000+0000" } ], "maxResults": 2, "total": 2, "startAt": 0 } } }