Archive for the 'Tutorials' Category

Appcelerator Titanium :: Upgrading tiapp.xml to the newer format, and define custom Info.plist values

Friday, August 3rd, 2012

If you are using Appcelerator Titanium there was an interesting entry I noted in the version 2.1.0 changelog:

Support for custom Info.plist values in tiapp.xml. Many of the existing iOS-specific tiapp.xml values are deprecated in favor of the new values

There are two items of interest here:

  1. Many existing tiapp.xml values are now deprecated.
  2. I can now set custom key/value pairs in the tiapp.xml file and they will be inserted into the projects Info.plist automatically when the project is built. I no longer need to manually maintain a custom Info.plist file in my project to set key/values that Titanium did not officially support. Yay!

The problem is that there is no example of exactly what these entries should look like in a final working tiapp.xml file. A new project created in Titanium Studio still creates the tiapp.xml file using the older / deprecated format. Even the latest KitchenSink sample project, that has just majorly reworked for the 2.1.1 release, is still using the deprecated format.

Here is an example of a now deprecated style tiapp.xml file, which most developers are still using:

<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
    <id>com.appcelerator.helloWorld</id>
    <name>helloWorld</name>
    <version>1.0</version>
    <publisher>not specified</publisher>
    <url>not specified</url>
    <description>not specified</description>
    <copyright>not specified</copyright>
    <icon>appicon.png</icon>
    <persistent-wifi>false</persistent-wifi>
    <prerendered-icon>false</prerendered-icon>
    <statusbar-style>default</statusbar-style>
    <statusbar-hidden>false</statusbar-hidden>
    <fullscreen>false</fullscreen>
    <navbar-hidden>false</navbar-hidden>
    <analytics>true</analytics>
    <guid></guid>
    <iphone>
        <orientations device="iphone">
            <orientation>Ti.UI.PORTRAIT</orientation>
        </orientations>
        <orientations device="ipad">
            <orientation>Ti.UI.PORTRAIT</orientation>
            <orientation>Ti.UI.UPSIDE_PORTRAIT</orientation>
            <orientation>Ti.UI.LANDSCAPE_LEFT</orientation>
            <orientation>Ti.UI.LANDSCAPE_RIGHT</orientation>
        </orientations>
    </iphone>
    <android xmlns:android="http://schemas.android.com/apk/res/android">
    </android>
    <modules>
    </modules>
</ti:app>

Note the following issues here:

  • The persistent-wifi section is deprecated in 2.1
  • The prerendered-icon section is deprecated in 2.1
  • The statusbar-style section is deprecated in 2.1
  • The statusbar-hidden section is deprecated in 2.1
  • The iphone section with the orientation settings is deprecated in 2.1

So what should this look like? And how do we set custom key/value entries to be included in the Info.plist?

Here is a working tiapp.xml file using the newer format:

<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
    <deployment-targets>
        <target device="mobileweb">false</target>
        <target device="iphone">true</target>
        <target device="ipad">true</target>
        <target device="android">true</target>
        <target device="blackberry">false</target>
    </deployment-targets>
    <sdk-version>2.1.1.GA</sdk-version>
    <id>com.imattsolutions.equipd</id>
    <name>Equipd Beta</name>
    <version>1.3.0</version>
    <publisher>iMatt Solutions</publisher>
    <url>http://www.imattsolutions.com</url>
    <description>Mobile App for Ministry and Bible Study</description>
    <copyright>2012 iMatt Solutions</copyright>
    <icon>Icon.png</icon>
    <fullscreen>false</fullscreen>
    <navbar-hidden>false</navbar-hidden>
    <analytics>false</analytics>
    <guid>0fcd52a3-02b0-4b6a-aed6-we234522sf</guid>
    <android xmlns:android="http://schemas.android.com/apk/res/android"/>
    <modules>
        <module platform="iphone" version="0.1.22">zipfile</module>
    </modules>
    <ios>
        <plist>
            <dict>
                <key>UIRequiresPersistentWiFi</key>
                    <false/>
                <key>UIPrerenderedIcon</key>
                    <true/>
                <key>UIStatusBarHidden</key>
                    <false/>
                <key>UIStatusBarStyle</key>
                    <string>UIStatusBarStyleBlackTranslucent</string>
                <key>UISupportedInterfaceOrientations</key>
                    <array>
                        <string>UIInterfaceOrientationPortrait</string>
                        <string>UIInterfaceOrientationPortraitUpsideDown</string>
                        <string>UIInterfaceOrientationLandscapeLeft</string>
                        <string>UIInterfaceOrientationLandscapeRight</string>
                    </array>
                <key>UIBackgroundModes</key>
                    <array>
                        <string>audio</string>
                    </array>
            </dict>
        </plist>
    </ios>
</ti:app>

Notice that all of the deprecated settings are now migrated to the new ios > plist > dict section, including an example of a custom key UIBackgroundModes that will be included in the generated Info.plist.

For a detailed description of all Info.plist keys, see the iOS Info.plist Key Reference on the iOS Developer Center.

You can read more about the specifics of the tiapp.xml file here.

I hope this helps developers convert their projects over to the new format – it certainly makes more sense long term to use this approach to setting custom key/value pairs in the Info.plist file that drives our projects.

Ctrl + Alt + Delete on a MacBook Pro

Thursday, October 6th, 2011

I just had to login to a windows server using VNC, and I was required to "Press CTRL + ALT + DELETE to log on". Not as easy as it sounds on a Mac laptop which has no "Alt" or "Delete" key. And a quick Google pointed to remapping keys on the keyboard which did not appeal to me.

After a bit of playing around I found the equivalent keystrokes that will work:

"control" + "option" + "fn" + "delete"

No keyboard remapping required.

Hopefully that saves you some time if you ever have the need.

Getting Xcode to put opening braces on a new line

Saturday, April 10th, 2010

By default Xcode (the Apple Developer IDE) puts opening braces at the end of the current line like so:


if ( condition ) {
     // code here...
}

However I have been working on projects for years with a different convention:


if ( condition )
{
    // code here...
}

Of course developers have different preferences here. One is not right and the other wrong – that is dictated by a company or by a project, or by the consensus of the developers starting a new project. Once a convention is in place then it must be adhered to for the life of the project. And of course a decent IDE will work with developers preferences.

So – how do we get Xcode to support this alternate convention? The problem being that there is no UI preference to set this.

To change this preference the quick way:

Open the Terminal App and paste the following code:


defaults write com.apple.Xcode XCCodeSenseFormattingOptions -dict BlockSeparator "\n"

Then restart Xcode. Thats it.

What does this do? It places a new entry in a plist file that is located in your user Home Directory. Home > Library > Preferences > com.apple.Xcode.plist.

Next time you start coding in Xcode it will autocomplete with opening braces on a new line.

Controlling the IE7 “Shrink to Fit” print setting using JavaScript

Friday, November 30th, 2007

You may have noticed that printing in Internet Explorer 7 has a new feature – "Shrink to Fit". In some situations, such as when pages are in an iFrame, "Shrink to Fit" is always applied by default. For general web pages this feature may be appreciated, but in a web application where developers want to control the layout of the page, and perhaps generate reports, we do not appreciate IE7's changing the print layout at all.

If you have not been challenged by this behaviour yet, don't worry – you will! And when you do, here is the solution.

Instead of the typical "print()" command in JavaScript, use:


document.execCommand('print', false, null);

Or if you are wanting to print a document inside an iFrame you can use something like:


window.frames(0).focus();
window.frames(0).document.execCommand('print', false, null);

Note: This solution is for Internet Explorer 7 only – I leave it up to you to do the browser detection.

Injecting JavaScript and CSS into Iframes

Sunday, April 15th, 2007

Introducing a new technique to allow efficient reuse of JavaScript and CSS – effectively allowing you to download the code once and then inject it into Iframes. This solution is targeted at Web Applications which commonly use Iframes for complex layouts and to control memory usage in larger apps without moving to the complexity of a Single Page Interface (SPI). Along the way we summarise and explain other methods available to developers for minimising their code and speeding up the loading time of their application.

With the next generation of Web Applications upon us the challenges faced by the average web developer have broadened. Understanding and confronting issues like memory leaks, bandwidth, load times and JavaScript processing time is becoming more of an everyday focus for web developers than ever before.

Fortunately we now have the tools available to help. On the developers machine the Web Developer Toolbar and Firebug for example are essential. And within the applications themselves we find increased usage of JavaScript libraries such as Dojo, jQuery, Prototype, YUI and widget frameworks like Ext, which provide a layer of abstraction and freedom for developers from some of these issues.

The increased usage of JavaScript however brings other challenges. Particularly in the world of Web Applications where the use of Widgets (tabs, grids, menus etc) is more likely, it is not uncommon for the volume of JavaScript and CSS to quickly accumulate from tens to a few hundred kb of code. This is a far cry from ideal, but is also to a certain extent unavoidable if that is the type of application you are supporting.

What can a developer do to minimise this issue? There are several very effective methods that can be explored:

Compacting Your Code
This is acheived by stripping out comments and unneccesary white-space which can drastically reduce the size of your files – sometimes cutting them in half. Recommended tools: Dean Edwards Packer or Douglas Crockford's JSMin. You could apply the same theory to your CSS as well.

File Compression
Using GZIP or Deflate can drastically reduce the downloaded file size (but should be used wisely). You can read more on this here.

Combining Multiple Files
In general browsers download only two or four files in parallel per hostname, depending on the HTTP version of the response and the user’s browser. On top of that it seems that JavaScript files are loaded synchronously and sequentially as they appear in your code. This means that only one JavaScript file can be downloaded at a time – and each file must be completely downloaded and then interpreted before the next download can begin. Reducing the number of HTTP requests by combining your JavaScript and CSS files into single files will definitely help improve your applications response times. Using CSS Sprites to combine your images into a single file and re-use with CSS is also an extension of this principle and is a very effective technique.

Caching
Server-side caching can help speed the up the delivery of page content. Also understanding browser caching and how to control this using file headers can make a difference – but again should be used wisely.

These techniques have been around for quite a while now. But this leads me to the real point of this post!

"Injection" Introduced

When it comes to the world of Web Applications (as opposed to a "website") where the use of Iframes is more likely, there is another technique that can be explored – "Code Injection".

I became aware of this technique while trying to interpret some very lengthy posts from Choleriker on the Ext forums. I thank Choleriker for taking the time to explain the concepts. I thought I would share my interpretation of this technique, as well as provide some examples to see it in action as requested by other developers in the forums.

First of all – what is this "code injection" that I am referring to?

Explained
In breif, the technique basically involves loading your JavaScript and CSS only once and then re-using it inside any iframes without downloading it again. This is acheived by loading your code "inline" inside the top level page of the application. The top page then makes the JavaScript and CSS available as two variables that can be called from the iframes directly. So the code is passed or "injected" from the top level page into any iframes using JavaScript.

Benefits?
There are several benefits to this technique – the most obvious being that you only download your JavaScript and CSS once, no additional downloads required. If you normally compress your JavaScript files using GZIP you likely know that there is a performance hit in the client browser to decompress the code before it can be used. This is no longer an issue for the reused code. And there is no longer any concerns with browser caching issues. Another big plus is that the CSS and JavaScript is being loaded as part of your actual page – i.e. there are no other additional files to download, which will improve the response times as described above.

Downsides?
I guess that the technique requires iframes. In time I guess/hope the principles of the technique may be able to be used in other perhaps more elegant ways that I haven't thought of yet. Another downside is the need to load your JavaScript and CSS inline. This was initially repugnant to me, mainly due to my background in website development. But in an Application is it really a big deal? I have decided it does not outweight the benefits.

Another perceived downside is that you have to get all of your JavaScript and CSS into a format that is loaded inline – but of course you still want to work with your separate "clean" files as you are used to. This should be viewed as an opportunity! It is likely time to implement a number of techniques as discussed above. My recommended technique is to have a server-side script that does the following:

  • Combines the required JavaScript and CSS files
  • Compacts the code by stripped white-space, comments etc
  • Caches the output code to a file on the server
  • Include the code inline using PHP or some other scripting language

I may provide some code for doing this in PHP in the future. In the meantime you might want to look at the "Combine" script from Niels Leenheer to get started.

Sample Application
So – how about an example? Click on the image below to see this technique in action. The example is built using Ext 1.0 Beta 2. It is a top level page which generates an Ext Layout with panels. The right-hand panel contains an iframe which receives the JavaScript and CSS from the top level page – it has not downloaded any files except the required images.

Launch Demo

The secret to this working is the following code in the Top Page:

<textarea id="StyleProxy" style="display:none;visibility:hidden;">
// CSS loaded inline here
</textarea>
<script type="text/javascript">
document.write(['<style type="text/css">',document.getElementById('StyleProxy').innerHTML,'</style>'].join('r'));
</script>
 
<script type="text/javascript" id="ScriptProxy">
// JavaScript loaded inline here
</script>
 
<script type="text/javascript">
// define the variables for storing the JavaScript and CSS
var _SCRIPTS = null;
var _STYLES = null;
 
// use jQuery to run the JS once HTML is loaded
$(document).ready( function()
{
    // place the JavaScript and CSS into the variables for reuse
    top.window._SCRIPTS = Ext.get("ScriptProxy").dom.innerHTML.toString();
    top.window._STYLES = Ext.get("StyleProxy").dom.innerHTML.toString();
 
    // create an iframe and add to the DOM
    // this should be always be done after the variables 
    // for the JS and CSS are filled 
    $main_container = Ext.get("iframe_main_container");
    var $iframe_nav = Ext.DomHelper.append (
        $main_container, {
         tag:         "iframe",
         id:          "iframeMain",
         name:        "iframeMain",
         width:       "100%",
         height:      "100%",
         frameborder: "no",
         scrolling:   "no",
         src:         "ext_demo_iframe1.htm"
        }
    );
})
</script>

A look at the files downloaded reveals the benefits – the iframe had nothing to download but the basic page itself. The JavaScript and CSS were downloaded only once as part of the top page. This top page was a reasonable size – but Ext is not small, and we can see the GZIP compression kicking in:

File Usage

Conclusion
So – should you use this technique? That depends on your application and your preference. The objective of this post was to simply introduce a concept that was new to me, and I am sure is new to many others. It is simply another technique to add to a developers toolbox.

PS: I am very interested what other developers think of this technique and what they perceive as the advantages and disadvantages. I also have a question – does this technique expose any security holes I should be aware of?

Should It Open a New Window?

Saturday, January 28th, 2006

One question I have been asking myself when writing this blog is – should external links in my blog open a new window by default, or should it stay in the current window? What is considered "best practice" nowadays? So I decided to do a bit of research. As usual when it comes to such topics the opinions are many and varied, and everyone thinks they are right. So I decided to share with the world my conclusions. :)

I have decided that it is best practice to not open new windows to external sites by default. Why?

  • New windows popping up can confuse inexperienced surfers who are used to the safety of the "Back" button. A new window does not retain the browser history of previous windows, thus rendering the Back button useless.
  • Experienced surfers know how to open new windows or tabs – let them choose. Tip: In Internet Explorer and Firefox hold down the "shift" key when clicking a link to open it in a new Window, or in Firefox use the "ctrl" key to open in a new Tab.

  • New windows opening up are a big problem for the visually impaired whose speech-to-text software may not have been warned of the window change, or they have missed hearing the warning that a new window was opened.

Of course, there are always exceptions to the rule. In some situations opening a new browser window is the logical thing to do – but not for every link by default.

If you do…

When/if you do want to open a new Window keep in mind that the target attribute of the <a> tag is deprecated, and will prevent your pages from validating in HTML 4.01 Strict, XHTML 1.0 Strict, or any future version. There are a number of alternative methods around – most of them using JavaScript. Here is the method I recommend:

<a href="http://google.com/" onclick="window.open(this.href); return false;">
  A Test Link
</a>

Here is a sample link using this code.

Why is this recommended method? It achieves our objective of opening a new window, but it also:

  • Preserves the href element for Search Engines
  • Users who want control can still right-click
  • The link can still be Bookmarked or added to the browser Favorites
  • Your code will validate

—————

So … future external links on this blog will not open a new window by default. And on the odd occasion it is a good idea, I will use the method outlined above.

If you have any thoughts on this topic I would love to hear them…

The lazy way to create a Favicon.ico

Friday, January 6th, 2006

The favicon.ico is a small icon file that sits at the root of your website. It will display next to your website details in the browser address bar and in a Favorites/Bookmarks list. I have created a ICO file for this website which you should see in the address bar right now – it looks like this How did I create it? It couldn't be easier:

  1. Use imaging software to create your image 16×16 (pixels).
  2. Use the online FavIcon from Pics tool to convert your image to an ICO file
  3. Follow the instructions from FavIcon from Pics:
    – Download the ICO file
    – Upload the ICO to the root folder of your website
    – Insert the code in your HTML as described

Done.