Installation and version management of mobile applications without any MDM solution

From my SCN blog post:

While testing applications, we used the below strategies and it took us some time to work these out. So I sum these up as reference – I trust people will find it useful. These are based on my experience in dealing with iOS apps.

Problem 1: I was working on an enterprise mobile application project but we couldn’t use the organisation’s pre-existing mobile device management ( MDM ) solution. This can happen due to any number of factors – in our case, the app was simply too big to be supported by the current version of MDM solution (it’s not a SAP MDM solution ).

Solution :

We used the below alternatives and they can be employed to work.

1. DropBox. A simple html page can be created in DropBox which points to the app’s plist file ( property list file ) and the plist file in turn will point to the relative location of the .app file. I kept the app in the Public folder of dropbox.

Let me draw a picture to make it clearer.

Screen Shot 2014-08-23 at 11.07.08 pm.png

2. TestFlight: I wasn’t aware of this site when we were first working on testing release I but found it extremely useful for subsequent releases. You can set up a project team, assign users to test and check the devices registered.

See the sample screenshot below.

Screen Shot 2014-08-23 at 6.png

3. Through a public site. You’ll need infrastructure team to create a publicly accessible domain ( if you want them to access via normal internet ).

Add the below MIME types to your web server ( for IIS ).

Mime type for plist -> application/xml

Mimet type for ipa -> application/octet-stream

4. The most obvious one : If the users can come to your desk, of course just use Xcode to install by making the device a developer device.

Hints on creating the HTML page:

a) Create the HTML page – this page will point to the plist file.


<a href=”itms-services://?action=download-manifest&url=“>Download App</a>

This will create a quick and dirty page for users to install the app.

Screen Shot 2014-08-23 at 5.58.09 pm.png

Of course, you can make it better by adding icons etc.

b) The plist file will in turn point to the .ipa file. You’ll need to edit it manually from the one generated by Xcode.

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” ““>

<plist version=”1.0″>























   <string>Name Of Application</string>






Problem 2: While testing we realised that sometimes the user’s app version was outdated and they’ll report issues or have inconsistencies due to a lower version. This can cause a lot of confusion.

Solution :


– Store the supported version of the app on a text file in an external URL .

– Get the version of the app and compare the version from an external URL.

– If the version in the app is lower than the supported version , display a message asking the user to upgrade and quit.

The supported version may not be the current version of the app – for minor UI tweaks, we may not change the supported version but if there are changes to the underlying object structure, the supported version will need to be changed.

Sample Objective-C code:  We can put it in the Main View Controller.

Main view controller :

    [self checkifObsoleteAppVersion];


– (void) checkifObsoleteAppVersion{


//Get version from external site

    NSString *versionURLString = @”http://URL/version.txt;  //<<– Version information stored in a simple text file

    NSURL *versionURL = [NSURL URLWithString:[versionURLStringstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSString *versionOnExternalSite = [[NSString stringWithContentsOfURL:versionURLencoding:NSUTF8StringEncoding error:nilsubstringToIndex:6];


//Get version from App

    NSString *versionFromApp = [self.syncManager.appVersion substringToIndex:6];


//Format the versions to numbers

    NSNumberFormatter *versionFromAppNo = [[[NSNumberFormatter alloc]init]autorelease];

    NSNumber *appNo = [ versionFromAppNo numberFromString:versionFromApp];


    NSNumberFormatter *versionFromAppNoExt = [[[NSNumberFormatter alloc]init]autorelease];

    NSNumber *appNoExt = [ versionFromAppNoExt numberFromString:versionOnExternalSite];


//App version shouldn’t be lower than the one maintained in version file


    if ([appNo floatValue] < [appNoExt floatValue] )



// Show a message

        UIAlertView *appObsoleteView = [[[UIAlertView alloc]initWithTitle:@”App version obsolete”message:@”A new version of App has been released and this version is obsolete.Please upgrade App to the new version.” delegate:self cancelButtonTitle:@”Exit” otherButtonTitles:nil, nil]autorelease];

        appObsoleteView.tag = 666;

        [appObsoleteView show];








Problem 3: Just putting as a reference to consolidate the information in a single place. Users were required to be manually registered and there were issues caused sometimes due to wrong information being set up due to manual process.



I created a solution using SUP’s Java APIs and shared the experience in an earlier blog.



iOS memory management

– All objects have a property retaincount.

– copy, new, alloc and retain increase retain count by 1.

– release decreases retain count.

-autorelease decreases retaincount when the current run loop gets finished.

– Can create your own autorelease pools and drain them to reclaim memory.

Zones: Without zones small and large objects will be created together causing fragmentation. With zones, system creates two different zones – separate ones for different sizes of objects.

– Objects returned by Cocoa are normally autoreleased.

-in dealloc : [aProperty release]

or [ = nil]

bugs : app crash: something has been released or auto released and is being accessed

memory leak : memory was allocated but hasn’t been reclaimed even though not required

With ARC : Memory gets deallocated when all strong variables pointing to it are deallocated.

Strong, weak and unsafe_retained:

Strong : Valid till runtime and automatically released. Default for all local variables.

Weak : Zeroes ( sets to null ) the weak reference . So if a weak property points to a strong property and the strong property is released – the weak property is set to null.

unsafe_retained: Doesn’t get set to nil but set to a dangling location in memory.

While declaring them inline, use double underscore ..

__strong etc.

Why is weak needed: To avoid circular references.

[obj1 setObject:obj2]

[obj2 setObject:obj1]

Now both have circular references