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:

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

pushnotifsymbol.js:

exports.id = '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, builder.tiapp.name + '_Prefix.pch');
        next();
    });
    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');
            }
        }
        next();
    });
};

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 ti.cloud 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);

Titanium app hex color value with alpha channel

Color values are represented in hexadecimal value:

#000000

  • 0 – red, 0 – green, 0 – blue
  • color = black

#ffffff

  • 255 – red, 255 – green, 255 – blue
  • color = white

‘ff’ in hexadecimal is 255 in decimal, (2 ^ 8) – 1 = 255.

In CSS, to represent color with alpha channel, we can use the rgba() syntax:

rgba(0, 0, 0, 0.6)

  • 0 – red, 0 – green, 0 – blue
  • black with 60% opacity

In Titanium, rgba() syntax only available on iOS, but hex value also can be used to represent alpha channel, and it supported by both iOS & Android

#ff000000

  • 0 – red, 0 – green, 0 – blue
  • ff – 255 / 100% opacity

#90ffcc00

  • 255 – red, 204 – green, 0 – blue
  • 90 – 144 / 56% opacity

To easily maintain colors in app, this function is to transform rgba value into Titanium hex color format

function rgbaToHex(r, g, b, a) {
    var toHex = function(n) {
        return ('00' + (n | 0).toString(16)).slice(-2);
    };
    return '#' + toHex(((a * 100) / 100) * 255) + toHex(r) + toHex(g) + toHex (b);
}

Explanation:

  • (n | 0) is shortcut for parseInt(), to ensure the value passed in is integer. We don’t want the hex color value to have decimal point, e.g: #2.4ccc
  • .toString(16) is Number object function (not Object.toString()) to convert number into hexadecimal format
  • ('00' + value).slice(-2) is to add string padding to the left of the string, so that it will always have 2 characters. We don’t want the value to have one character, #0ccff is invalid value

Usage:

var view = Ti.UI.createView({
    backgroundColor: rgbaToHex(255, 204, 0, 0.5)
});

ActionBarImplBase can only be used with a compatible window decor layout

ActionBarImplBase can only be used with a compatible window decor layout

This error occured in android 2.3 if you’re trying to use ActionBar feature on theme that disable ActionBar

Let’s say you define a style that enable actionbar overlay mode

<style name="MyTheme" parent="Theme.AppCompat">
     <item name="android:windowActionBarOverlay">true</item>
     <item name="windowActionBarOverlay">true</item>
</style>

Then one style extends this base style, but disable the actionbar

<style name="MyDifferentTheme" parent="MyTheme">
     <item name="android:windowActionBar">false</item>
     <item name="windowActionBar">false</item>
</style>

This will cause the crash. To fix it, the new style either need to extend different parent style, or disable the actionbar feature

<style name="MyDifferentTheme" parent="MyTheme">
     <item name="android:windowActionBar">false</item>
     <item name="windowActionBar">false</item>
     <item name="android:windowActionBarOverlay">false</item>
     <item name="windowActionBarOverlay">false</item>
</style>