[TIMOB-13665] Ti API: Provide a means for native modules to be active during app startup before app.js loads
GitHub Issue | n/a |
Type | New Feature |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2014-01-28T19:10:17.000+0000 |
Affected Version/s | n/a |
Fix Version/s | 2013 Sprint 10 API, 2013 Sprint 10, Release 3.1.1, Release 3.2.0 |
Components | iOS, TiAPI |
Labels | qe-closed-3.1.1 |
Reporter | Blain Hamon |
Assignee | Blain Hamon |
Created | 2013-04-24T01:41:15.000+0000 |
Updated | 2014-01-28T19:10:17.000+0000 |
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:
Indicating a module needs to start early. This is a property of the module.
Allow a module to optionally run during the app startup (EG, AppDidFinishLaunching on iOS)
Allow a module to optionally run before the app.js is processed and run.
Allow a module to optionally run after the app.js is processed and run.
Due to the short time needed, these will be OS-specific, but allow for commonality where logical.
Implementation will probably be thusly:
* A module's manifest includes a boolean to allow it to run early. (Does this need to happen? Perhaps we can introspect it?)
* The module template and/or a protocol will indicate what class/static method names will be.
* 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.
* The application, on startup, will know what module classes to method call, and call thusly.
* The application will broadcast (NSNotifications during AppDidFinishLaunching, before calling willStartNewContext, after calling didStartNewContext; and android equiv )
* By adding notificationListeners/(Android equiv) during the early method call, the module can execute whatever it wants during those specific points.
Attachments
File | Date | Size |
dancer.zip | 2013-05-20T21:24:52.000+0000 | 124064 |
From Allen for Android: It 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: @Kroll.onAppCreate public static void onAppCreate(TiApplication app) { Log.d(TAG, "inside onAppCreate"); // put module init code that needs to run when the application is created } Both Soasta and crittercism should be able to place their initialization code there.
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. The 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.
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: * +[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. * TiBindingRunLoopCallOnStart(TiBindingCallback, void *) adds a callback that will be run every time a run loop is started, before the file is executed. So, to test:
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.
CR &FR on both master & 3_1_X
Testing Instruction.
* 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/). * Create a new app and make sure you add the new module(ti.testmodule) in tiapp. * Build the app and run it. * Check log to see the following outputI'm doing a little dance for KrollContext<somevalue>
To use: Build module, use in app. Note debug message about dancing with KrollContext.
Verified working as expected, showing the expected message
Environment: Appcelerator Studio 3.1.1.201305292130 Titanium SDK 3.1.1.v20130529114554 Alloy 1.1.3-alpha Titanium-Code-Processor 1.1.3-alpha3 Closing.