Noodlecode parody of spaghetti code

Creating [object] in a different context than the calling function.

Creating [object] in a different context than the calling function.

This warning occured when a JS callback function is passed to Objective-C as KrollCallback and then executed on non-JS thread.

KrollCallback *callback = [args objectForKey@"callback"];

[OneSignal initWithLaunchOptions:[TiApp app].launchOptions appId:appId handleNotificationAction:^(OSNotificationResult *result) {
    [callback call:@[] thisObject:nil];

Problem with this warning is, if the JS callback create Ti.Network.HTTPClient instance, then that instance is null.

function callback() {
    var http = Ti.Network.createHTTPClient();'GET', getUrl()); // JS error! http is null

To fix, get krollContext instance of current module/proxy and execute callback inside invokeBlockOnThread

// For TiModule / TiProxy descendants
KrollContext *context = [self.executionContext krollContext];

// For TiUIView descendants
KrollContext *context = [self.proxy.executionContext krollContext];

// invoke
[context invokeBlockOnThread:^{
    [callback call:@[] thisObject:nil];

Download youtube video as audio file

Note: using Mac OS X 10.10.5

Install Homebrew

Install youtube-dl

$ brew install youtube-dl

Install ffmpeg

$ brew install ffmpeg

To download & save as audio file

$ youtube-dl -x --audio-format mp3 --prefer-ffmpeg [URL]

Activity & fragment lifecycle events

1. Start new activity

Activity, onCreate
Fragment, onAttach
Fragment, onAttach
Fragment, onCreateView
Fragment, onActivityCreated
Fragment, onStart
Activity, onStart
Activity, onResume
Fragment, onResume

2. Close activity (tap back button)

Fragment, onPause
Activity, onPause
Activity, onStop
Fragment, onDestroyView
Fragment, onDestroy
Fragment, onDetach
Activity, onDestroy

3. Hide activity (tap home button)

Fragment, onPause
Activity, onPause
Activity, onStop

4. Resume activity (from home screen)

Activity, onRestart
Fragment, onStart
Activity, onStart
Activity, onResume
Fragment, onResume

5. Go to other activity

Fragment, onPause
Activity, onPause
Activity, onStop

6. Resume from other activity (return back)

Activity, onRestart
Fragment, onStart
Activity, onStart
Activity, onResume
Fragment, onResume

Compress / Decompress files using XZ


xz -zk myfile.txt

will produce myfile.txt.xz in the same directory


xz -dkc myfile.txt.xz > myfile.txt

Titanium Studio mark occurences

Preferences > Titanium Studio > Editors > JavaScript, check “Mark occurrences with background color”.


Ti.Network.registerForPushNotifications no response

SDK: 3.5.1.GA, CLI: 4.0.1

Calling Ti.Network.registerForPushNotifications() has no response, whether success, error or callback, basically no response at all. Turned out that the build script can’t detect the method and add USE_TI_NETWORKREGISTERFORPUSHNOTIFICATIONS to defines.h during app compilation.

I created with a plugin that append the macro definition to *.pch file, here it is:

Create plugin folder:

mkdir -p plugins/ti.pushnotifsymbol/hooks
touch plugins/ti.pushnotifsymbol/package.json
touch plugins/ti.pushnotifsymbol/hooks/pushnotifsymbol.js

pushnotifsymbol.js: = 'ti.pushnotifsymbol';
exports.cliVersion = '>=3.2';
exports.init = function (logger, config, cli) {
    var path = require('path');
    var fs = require('fs');
    var util = require('util');
    var os = require('os');
    var pchFile;
    var triggered = false;
    cli.on('build.pre.compile', function(builder, next) {
        pchFile = path.join(builder.buildDir, + '_Prefix.pch');
    cli.on('build.ios.copyResource', function(builder, next) {
        if (!triggered) {
            triggered = true;
            if (fs.existsSync(pchFile)) {
                fs.appendFileSync(pchFile, os.EOL + '#define USE_TI_NETWORKREGISTERFORPUSHNOTIFICATIONS');

Add <plugin>ti.pushnotifsymbol</plugin> to <plugins> section of your project tiapp.xml

Titanium iOS builder script

Location: TITANIUM_SDK/mobilesdk/osx/3.5.1.GA/iphone/cli/commands/_build.js
(TITANIUM_SDK is commonly at ~/Library/Application Support/Titanium)

1. Cannot change CFBundleVersion

  • CFBundleVersion is the build version number, available to developer and beta testers.
  • CFBundleShortVersionString is the release version number, what the users see on App Store
  • CFBundleVersion is automatically assign to value of <version> in tiapp.xml, but for beta testing purposes, need to change this value everytime we upload new build to iTunes Connect TestFlight
  • To fix this, modify iOS builder script in iOSBuilder.prototype.createInfoPlist() function, around line 2063
plist.CFBundleVersion = String(this.tiapp['build-version'] || this.tiapp.version);

2. If your Titanium SDK location is different from default (custom SDK path), the script doesn’t look up that folder when searching for modules

  • My Titanium SDK is located at ~/Applications/opt/Titanium, when running the ti build -p ios command, it doesn’t lookup for modules there
  • If my project included module, the build script will fail, cannot find the specified module
  • To fix this, in iOSBuilder.prototype.validate() function
// around line 1321, add:
customSDKPaths = config.get('paths.sdks'),

// around line 1331, add:
Array.isArray(customSDKPaths) && customSDKPaths.forEach(addSearchPath);

Git remotes

LIst out all remotes:

git remote -v

Show info about a remote:

git remote show origin

Titanium Android keystore

Location: TI_SDK/mobilesdk/osx/3.5.1.GA/android/dev_keystore
Alias: tidev
Password: tirocks


Android BOOT_COMPLETED handler module

This Titanium Android module provide a place where you can run your JS script when the device receives BOOT_COMPLETED broadcast intent. By simply adding boot_completed.js into your Resources folder, this JS file will be run when the broadcast intent received.

Continue reading

« Older posts

Copyright © 2016 Noodlecode