Noodlecode parody of spaghetti code

Month: September 2013 (page 1 of 3)

Logcat

To use logcat to debug Android app

  1. Install Android SDK
  2. Add c:\Android\android-sdk\platform-tools\adb.exe to PATH

Command:

  • get list of connected devices, will return device serial number
    adb devices
  • filter logcat by tag (e.g by “TiAPI” tag)
    adb -s <DEVICE_SERIAL_NUM> "TiAPI"

Load nib file in Titanium module iOS

When creating Titanium module for iOS platform, sometimes we need to include xib (NeXT Interface Builder) file. But if we include the file just like that, then we will face this error

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/username/Library/Application Support/iPhone Simulator/6.1/Applications/<app id>/myiosmodule.app> (loaded)' with name 'MyView''

To fix, we need to include a compiled xib file known as nib file. To compile it, you need to include it in a native iOS project & build it.

Update: Easier way to compile xib to nib file is using ibtool

$ ibtool MPAdBrowserController.xib --compile MPAdBrowserController.nib

Compile xib to nib file

For example here, I’m create mopub module for iOS

  1. Open Xcode, create new project, and choose ‘Single View Application’
    new-project-option
  2. Add xib file to the project
    add-file
    select-xib-file
  3. Make sure it is included in the ‘Copy Bundle Resource’ list, then click ‘Run’ button to launch the sample app in simulator
    copy-bundle-run
  4. After it runs on simulator, using Finder go to /Users/username/Library/Application Support/iPhone Simulator/6.1/Applications/<app id>/test.app, then see package content
    open-simulator-folder-2
    show-package-content
  5. You’ll find the nib file there. Put this nib file into /assets/ folder of TItanium module. Then you need to edit the path to load nib file in initWithNibName method.
    edit-code-init

In case you can’t edit the source Objective-C file, you have to put the nib file into /Resources/iphone/ folder of the app project

Enable x86 libs in production build Titanium app

In Titanium studio when we build an apk for production, it doesn’t include x86 libs which cause this exception occur on users device, and the app force close immediately after launch:

KrollRuntimeThread msg:java.lang.UnsatisfiedLinkError: Couldn't load stlport_shared: findLibrary returned null;

There’s a line of code in Titanium build script build.py that disable it in production settings, which the reason is unknown (last time it was because there are not many x86 devices out there, but it’s different now).

To enable x86 libs in production, comment out this line of code from build.py (mobilesdk/<os>/<version>.GA/android/build.py)

for abi in self.abis:
  lib_source_dir = os.path.join(sdk_native_libs, abi)
  lib_dest_dir = 'lib/%s/' % abi
# if abi == 'x86' and ((not os.path.exists(lib_source_dir)) or self.deploy_type == 'production'):
#   # x86 only in non-production builds for now.
#   continue

Source: http://developer.appcelerator.com/question/154006/x86-libs-not-included-in-production-apk

Titanium iOS “build” is an unrecognized command

Was trying to build an iOS app using sdk 3.1.2 but got this error.

[ERROR] "build" is an unrecognized command

When running titanium build command on the project folder, I realize that only Titanium CLI was updated to version 3.1.2 while its SDK still in 3.1.1

Updating the SDK solve this problem, by running this command

titanium sdk install 3.1.2.GA

Indirect code execution flow

Intro: we have an Android app, with typical main and detail window structure.

Let’s see this situation: when user tap a button on main window and then open a detail window, later when user closes the detail window, it needs to update the main window UI.

Here, we have two method of how to update the UI – proactive / direct way, or passive / indirect way.

First, there are several point during detail window closing process, which we can run the function to update the main window UI.

  • when user press back button on detail window
  • when detail window close event
  • when main window resumed

Direct way – when running the function to update main window UI during the 1st and 2nd point above.

// in detail window class

detailWindow.addEventListener('androidback', function() {
	mainWindow.updateUI();
	detailWindow.close();
});

// or

detailWindow.addEventListener('close', function() {
	mainWindow.updateUI();
});

Some disadvantages for this method:

  • detail window need to keep a reference to main window.
  • if updateUI() function take some time, then closing detail window will be delayed

Therefore, to ensure responsiveness of the app, we need to utilize indirect way of executing the code. When main window resume, we run the code to update the UI. But, what if we need to update the UI only when user close the detail window? Here, we need a state variable (variable that keeps track of a state).

// in main window class

var detailWindowOpened = false;
btn.addEventListener('click', function() {
	detailWindowOpened = true;
	detailWindow.open();
});

detailWindowOpened is the state variable, it tracks whether detail window has been opened or not.

// in main window class

mainWindow.activity.addEventListener('resume', function() {
	if (detailWindowOpened) {
		updateUI();
		detailWindowOpened = false;
	}
});

Then, when main window resume, it will automatically update its UI. So here, we don’t need to keep a reference of main window inside detail window class, and closing detail window won’t be delayed.

WrestleMania 19

WrestleManiaXIX
Continue reading

WrestleMania 18

WrestleManiaX8
Continue reading

WrestleMania 17

WrestleManiaX-Seven
Continue reading

WrestleMania 16

WrestleMania2000
Continue reading

WrestleMania 15

WrestleManiaXV
Continue reading

Older posts

Copyright © 2017 Noodlecode