{ "id": "113327", "key": "TIMOB-13665", "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": [ { "id": "15486", "description": "2013 Sprint 10 API", "name": "2013 Sprint 10 API", "archived": true, "released": true, "releaseDate": "2013-05-20" }, { "id": "15108", "description": "2013 Sprint 10", "name": "2013 Sprint 10", "archived": true, "released": true, "releaseDate": "2013-05-20" }, { "id": "15478", "description": "Release 3.1.1", "name": "Release 3.1.1", "archived": true, "released": true, "releaseDate": "2013-06-17" }, { "id": "14982", "description": "Release 3.2.0", "name": "Release 3.2.0", "archived": false, "released": true, "releaseDate": "2013-12-19" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2014-01-28T19:10:17.000+0000", "created": "2013-04-24T01:41:15.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "qe-closed-3.1.1" ], "versions": [], "issuelinks": [ { "id": "28140", "type": { "id": "10000", "name": "Blocks", "inward": "is blocked by", "outward": "blocks" }, "outwardIssue": { "id": "112945", "key": "TIMOB-13594", "fields": { "summary": "Replace code injection mechanism for Crittercism/SOASTA with auto-load approach", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2014-01-28T19:10:17.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" }, { "id": "10224", "name": "TiAPI", "description": "This component is used for cross-platform API work. Specifications are most likely to use this component." } ], "description": "There are some times where external code must be run very early on, or during specific times. Native Titaniums need to provide a means for:\r\n\r\n# Indicating a module needs to start early. This is a property of the module.\r\n# Allow a module to optionally run during the app startup (EG, AppDidFinishLaunching on iOS)\r\n# Allow a module to optionally run before the app.js is processed and run.\r\n# Allow a module to optionally run after the app.js is processed and run.\r\n\r\nDue to the short time needed, these will be OS-specific, but allow for commonality where logical.\r\n\r\nImplementation will probably be thusly:\r\n\r\n* A module's manifest includes a boolean to allow it to run early. (Does this need to happen? Perhaps we can introspect it?)\r\n* The module template and/or a protocol will indicate what class/static method names will be.\r\n* The application build scripts/CLI will read from the module manifests and leave some message for the application to know what module classes to call the method.\r\n* The application, on startup, will know what module classes to method call, and call thusly.\r\n* The application will broadcast (NSNotifications during AppDidFinishLaunching, before calling willStartNewContext, after calling didStartNewContext; and android equiv )\r\n* By adding notificationListeners/(Android equiv) during the early method call, the module can execute whatever it wants during those specific points.", "attachment": [ { "id": "38759", "filename": "dancer.zip", "author": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-05-20T21:24:52.000+0000", "size": 124064, "mimeType": "application/zip" } ], "flagged": false, "summary": "Ti API: Provide a means for native modules to be active during app startup before app.js loads", "creator": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [ { "id": "248947", "author": { "name": "ngupta", "key": "ngupta", "displayName": "Neeraj Gupta", "active": true, "timeZone": "America/Los_Angeles" }, "body": "From Allen for Android:\nIt looks like we already have a hook to perform some tasks before app.js is loaded. When you create a new module, there should be a method onAppCreate() inside the module.java class:\n\n@Kroll.onAppCreate\npublic static void onAppCreate(TiApplication app)\n{\n Log.d(TAG, \"inside onAppCreate\");\n // put module init code that needs to run when the application is created\n}\n\nBoth Soasta and crittercism should be able to place their initialization code there.", "updateAuthor": { "name": "ngupta", "key": "ngupta", "displayName": "Neeraj Gupta", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-24T18:57:40.000+0000", "updated": "2013-04-24T18:57:40.000+0000" }, { "id": "249426", "author": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Agreed. Android does have onAppCreate as a static/class method for modules and this launches early in the lifecycle. There should be a class method on iOS, but the OS doesn't use the 'onFoo' motif. The iOS modules are very loosely loaded, and while there is the ability to have things in applicationMods, this file is not used during simulator loads. This will require no work on Android, and changes to the CLI and SDK on iOS.\n\nThe next step, then is to allow the modules to inject into the spots mentioned. iOS already provides NSNotificationCenter, so this will be a relatively easy task. Android, I'm still looking into.", "updateAuthor": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-29T20:52:21.000+0000", "updated": "2013-04-29T20:52:21.000+0000" }, { "id": "252501", "author": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Okay, I should have known this. Obj-C has +[load] that happens whenever the code is loaded (IE, before the app even starts). This allows for registering for app lifespan events (AppDidFinishLoading, etc). However, for things where you want to inject right into the runtime, (Where we can't use NSNotificationCenter, due to nc's thread unsafety), there's two new APIs:\n\n* +[TiProxy performSelectorDuringRunLoopStart:] Convenience method for the C function, especially for autoloading modules. The selector is a class method taking one argument, which is the TiBindingRunLoop started.\n* TiBindingRunLoopCallOnStart(TiBindingCallback, void *) adds a callback that will be run every time a run loop is started, before the file is executed.\n\nSo, to test:\n{code}\n+(void)doALittleDance:(TiBindingRunLoop)runLoop\n{\n\tNSLog(@\"I'm doing a little dance for %@\",runLoop);\n}\n\n+(void)load\n{\n\tNSLog(@\"I'mma do a little dance.\");\n\t[self performSelectorDuringRunLoopStart:@selector(doALittleDance:)];\n}\n{code}", "updateAuthor": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-05-17T03:02:51.000+0000", "updated": "2013-05-17T03:02:51.000+0000" }, { "id": "252546", "author": { "name": "jenglish", "key": "jenglish", "displayName": "Jeff English", "active": true, "timeZone": "America/Chicago" }, "body": "FWIW, the +[load] mechanism is used in the ti.newsstand module since there are calls that must be made during application startup. The current module startup method is called too late in the process and also only if the main app.js requires it.", "updateAuthor": { "name": "jenglish", "key": "jenglish", "displayName": "Jeff English", "active": true, "timeZone": "America/Chicago" }, "created": "2013-05-17T13:59:39.000+0000", "updated": "2013-05-17T13:59:39.000+0000" }, { "id": "252597", "author": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "body": "CR &FR on both master & 3_1_X", "updateAuthor": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-05-17T17:49:19.000+0000", "updated": "2013-05-17T17:49:19.000+0000" }, { "id": "252843", "author": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "body": "h4.Testing Instruction.\r\n\r\n* Download and install [this|https://dl.dropboxusercontent.com/u/43336767/TIMOB-13665/ti.testmodule.zip] native module in the right Location (~/Library/Application\\ Support/Titanium/modules/iphone/).\r\n* Create a new app and make sure you add the new module(ti.testmodule) in tiapp.\r\n* Build the app and run it.\r\n* Check log to see the following output `I'm doing a little dance for KrollContext`\r\n\r\n", "updateAuthor": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-05-20T17:58:20.000+0000", "updated": "2013-05-20T17:59:53.000+0000" }, { "id": "252909", "author": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "To use: Build module, use in app. Note debug message about dancing with KrollContext.", "updateAuthor": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-05-20T21:24:52.000+0000", "updated": "2013-05-20T21:24:52.000+0000" }, { "id": "254912", "author": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified working as expected, showing the expected message\r\n{code}\r\nMay 30 11:38:23 iPhone classicProject[33853] : I'm doing a little dance for \r\n{code}\r\n\r\nEnvironment:\r\nAppcelerator Studio 3.1.1.201305292130\r\nTitanium SDK 3.1.1.v20130529114554\r\nAlloy 1.1.3-alpha\r\nTitanium-Code-Processor 1.1.3-alpha3\r\n\r\nClosing.", "updateAuthor": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-05-30T18:40:32.000+0000", "updated": "2013-05-30T18:40:32.000+0000" } ], "maxResults": 10, "total": 10, "startAt": 0 } } }