On my work, technology and related stuff....

Posts Tagged ‘iOS’

No comments

The Problem…

If you have been using Xcode  (the latest version as of writing this post is Xcode 4.6.2 ) for an extended period of time, testing your app on the iOS simulator, you may eventually encounter a “Resource temporarily Unavailable” build error . There are no build errors associated with your source code but the system is unable to successfully build your app and launch the simulator to run it . You would observe something like this in your build output.

 

 

So what’s going on?

The reason this occurs is because every time you launch the iOS simulator through Xcode to run your app and then quit /stop running the app, Xcode leaves behind a Zombie process.  If you are not familiar with Zombie processes in Unix, essentially, it is a process that has completed execution but whose entry remains in the process table. It is the responsibility of the parent process to eventually clear these processes. The zombies don’t use any of the computer resources so you won’t observe a depletion of resources , but the problem is that in this “undead” state, they hold on the PID or Process Identifier. The implication of this is that eventually, your system will run out of PIDs to assign to new processes, thereby resulting in a failure to spawn or launch a new process.

You can confirm this behavior by running your iOS app through Xcode a few times and then running the “ps” command on the terminal window. You will observe a bunch of zombie processes listed for your app. The “Z” in the “S” (or “STAT” ) column indicates that “symbolic state” of the process is a “Zombie“.

In my case, there were 272 zombie processes associated with my app that Xcode didn’t reclaim. So in case of the Xcode, you will eventually notice that you are no longer able to build the app and launch the simulator to run it. In fact, you probably won’t be able to launch  any new application. Yep- not a good place to be.

So what are your options?

Reboot:

The simplest and safest method is to reboot your system. This will get rid of the zombie processes

Re-initializing/Killing the Parent Process:

Generally , killing the  parent process corresponding to the Zombie processes should take care of it but unfortunately, in the case of Xcode, the parent process is the system launchd process. The launchd is a core system process that handles the launching of many of the other processes.  Issuing a “kill” command to the launchd process can result in undesirable results and can even make your system unresponsive. So DO NOT kill the launchd process. You could try to re-initialize the process using the kill with HUP (“Hang Up”) option but you are probably better off rebooting your Mac.

If you are curious, you can follow the steps below to determine the parent process of the Zombie Xcode process

1) You can identify the PID  (“ppid”) of the parent process corresponding to the zombie process using the command

This will output the ppid of the parent process corresponding to the Zombie process,

2) You can get details of the parent process using the following command

The output of the above command indicates that the launchd process is parent process.

You can find more details on Zombie processes at you can check out  the details in http://en.wikipedia.org/wiki/Zombie_process.

32 comments

This post describes how to invoke a SOAP based web service from your iOS app. The post is not going to dwell into the discussion of SOAP based versus a RESTful service and neither is it intended to be a tutorial on SOAP. For more information on the latter,there are plenty of online resources including the W3C (http://www.w3.org/TR/soap/). This post assumes that your needs require invocation of SOAP based web services from your iOS app.

We will use a free online web service http://www.webservicex.net/CurrencyConvertor.asmx?WSDL for our example. This is a very simple web service handles currency conversions (surprise!).

I recommend a free utility called "wsdl2objc" which generates client-side Objective-C code from a SOAP Web Services Definition File (WSDL) file. You can always construct the SOAP request messages and parse the SOAP responses on your own without the tool, however, the tool does a lot of the heavy lifting and is convenient.

1. Download the wsdl2objc tool from http://code.google.com/p/wsdl2objc/

2. Run the wsdl2objc tool . Enter the source URL for the WSDL and the destination folder for the generated ObjC files and select "Parse WSDL" button. A screenshot of the same is shown below

3. Once the "Parse WSDL" process completes, you should see a number of ObjC files in the destination folder.

4. Follow the following steps to integrate the ObjC files into your app.
4a) Copy the ObjC files that were generated in the previous step to your app project. Make sure you select the "Copy Files Into Destination Folder" option.
Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-copyfiles.png

4b) If you are using ARC in your project, you will have to disable ARC for the generated ObjC files. To do this, go to the "Compile Sources" section of "Build Phases" of your project and specify the "-fno-objc-arc" compiler flag for all the generated files.
Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-disableARC.png

4c) If you already have libxml2 installed on your system (look for libxml2.dylib in /usr/lib folder), then skip this step. Otherwise, follow the steps in (4c) to install libxml2 library
4c-1)  Install the macports package installer from http://www.macports.org/install.php (if you don't have it already)
4c-2) Install libxml2 library by executing the following command in a terminal window
        sudo port install libxml2

(*Tip* For the build to work for libxml2, make sure you have the command line tools installed for Xcode )

4d) In the target "Build settings", include "-lxml2" in the "Other Linker Flags"  property
Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-linkerflags.png

4e) In the target "Build settings", include "$(SDKROOT)/usr/include/libxml2" in the "Header Search Paths"  property

Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-headerfiles.png

4f) Import "CurrencyConvertorSvc.h" file into your implementation file and use the methods provided by this interface to make the appropriate web services calls.

The following code snippet demonstrate its usage

-(void)processRequest

{

    CurrencyConvertorSoapBinding* binding = [CurrencyConvertorSvcCurrencyConvertorSoapBinding];

    CurrencyConvertorSoapBindingResponse* response;

    CurrencyConvertorSvc_ConversionRate* request = [[CurrencyConvertorSvc_ConversionRatealloc]init];

    request.FromCurrencyCurrencyConvertorSvc_Currency_enumFromString(self.fromCurrencyTextField.text);

    request.ToCurrency = CurrencyConvertorSvc_Currency_enumFromString(self.toCurrencyTextField.text );

    response = [binding ConversionRateUsingParameters:request];

 

    dispatch_async(dispatch_get_main_queue(), ^{

        [self processResponse:response];

    });

}

 

 

-(void) processResponse: (CurrencyConvertorSoapBindingResponse*)soapResponse

{

    NSArray *responseBodyParts = soapResponse.bodyParts;

    id bodyPart;

    [self.activitystopAnimating];

    [self.activityremoveFromSuperview];

    @try{

        bodyPart = [responseBodyParts objectAtIndex:0]; // Assuming just 1 part in response which is fine

 

    }

    @catch (NSException* exception)

    {

        UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:@"Server Error"message:@"Error while trying to process request"delegate:selfcancelButtonTitle:@"OK"otherButtonTitles: nil];

        [alert show];

        return;

    }

 

    if ([bodyPart isKindOfClass:[SOAPFault class]]) {

 

        NSString* errorMesg = ((SOAPFault *)bodyPart).simpleFaultString;

        UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:@"Server Error"message:errorMesg delegate:selfcancelButtonTitle:@"OK"otherButtonTitles: nil];

        [alert show];

    }

    elseif([bodyPart isKindOfClass:[CurrencyConvertorSvc_ConversionRateResponseclass]]) {

        CurrencyConvertorSvc_ConversionRateResponse* rateResponse = bodyPart;

        UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:@"Success!"message:[NSStringstringWithFormat:@"Currency Conversion Rate is %@",rateResponse.ConversionRateResult] delegate:selfcancelButtonTitle:@"OK"otherButtonTitles: nil];

        [alert show];

 

    }

 

}

 

An example project can be downloaded from the following link-  SOAP Test. The project has been built using Xcode 4.5.

6 comments

If you have an iPhone app or are developing one, with the launch of iPhone5 , you  need to ensure that your images scale to support the new taller retina display (640X1136).

In case of the launch image, naming the new launch with the suffix "-568h@2x" (e.g.. Default-568h@2x) will ensure that the system picks up the right launch image for the iPhone5.

However, just adding the "-568h@2x" to the new images is not sufficient to have the system pick the right images for the tall retina display. Here is a very simple category on UIImage that can be used to return the right image. Note that in the category implementation, I assume that all the iPhone5 specific images are named with a suffix of "-568h@2x".

 

The "UIImage+iPhone5extension.h" Interface definition

 

 

 

The "UIImage+iPhone5extension.m" file implementation

 

 

Just include the above files in your project and replace relevant occurrences of [UIImage imageNamed:] call with [UIImage imageNamedForDevice:]. This would ensure that right image is picked up for non-retina,retina and tall retina versions of the resolution.

 

10 comments

If you are interested in developing software (apps, tweaks) for a jailbroken iOS device, then check out my presentation on Developing For Jailbroken iOS platform that I gave at a recent CocoaHeads meeting. This should be a good starting point. The presentation discusses the pros and cons of developing for a jailbroken phone, the various development tools (XCode, Theos) and frameworks (Mobile Substrate) that are available for building applications / run-time patches as well as other relevant information on jailbroken phones (SHSH blobs, jailbreak software etc).

I own an Apple Developer's License and build Apple certified apps for the App Store. I pursue this as a hobby. So hopefully the presentation will get you started.

22 comments

iOS devices support the delivery of multimedia content via HTTP progressive download or HTTP Live streaming . As per Apple's guidelines to App developers, "If your app delivers video over cellular networks, and the video exceeds either 10 minutes duration or 5 MB of data in a five minute period, you are required to use HTTP Live Streaming. (Progressive download may be used for smaller clips.)". 

This article discusses a method for generating HTTP live streaming content using freely available tools. If your needs are large scale, then you may need to explore commercial encoders such as the Sorenson Squeeze 7 or other commercial video platforms. This article does not describe commercial video platforms. 

HTTP Live Streaming – A (Very) Brief Overview:

 In HTTP Live streaming, the multimedia stream is segmented into continuous media segments wherein each media chunk/segment holds enough information that would enable decoding of the segment. A playlist file is a list of media URIs, with each URI pointing to a media segment. The media URI’s are specified in the order of playback and the duration of the playlist file is the sum of the durations of the segments. Media playlist files have an “.m3u8” extension. The servers host the media segments and the playlist file. In order to playback content, the media streaming app on the device fetches the playlist file and the media segments based on the media URIs specified in the playlist . The transport protocol is HTTP.
Now, you can have multiple encodings/renditions of the same multimedia content. In this case, you can specify a variant playlist file that will contain URIs to the playlist files corresponding to each rendition of content. In this case, the iDevice can switch between the various encodings thereby adapting to changing network bandwidth conditions. HTTP Live Streaming is essentially a form of adaptive streaming. You can get more details from the IETF I-D available here. Other well-known adaptive streaming protocols include that of Microsoft’s Smooth Streaming , Adobe’s Dynamic Streaming  and the DASH standards specification .

Encoding the content using Handbrake:

  1. Among the free tools, I’ve found Handbrake to be the best in terms of performance and supported formats. Versions are available for Windows and the Mac. In my experience, the Mac version stalled a few times during encoding and at times hogging all the CPU cores on my Macbook Pro. The Windows version worked flawlessly.

  2.  Use the following encoding guidelines provided by Apple to encode your content. If you expect your app users to be able to access the content under a variety of network conditions (wifi, cellular etc), you would want to support multiple encodings of the content .

 
 
 

The Tools for generating content for HTTP Live Streaming :

Once you have encoded your content, you would have to prepare it for delivery via HTTP live streaming. There are a command line utilities available for the Mac that can be downloaded for free from  http://connect.apple.com/ (You would need an Apple developer Id for installing the tools, which again is free). You would need the following tools –

  • mediafilesegmenter

  • variantplaylistcreator

Once installed, they would be available in/usr/bin directory of your Mac.

 Segmenting your encoded content:

Use the mediafilesegmenter tool to segment the encoded media files.  You would need to be “root” user in order to run the tool.
 
/usr/bin/mediafilesegmenter [-b | -base-url <url>]
                        [-t | -target-duration duration]
                        [-f | -file-base path] [-i | -index-file fileName]
                        [-I | -generate-variant-plist]
                        [-B | -base-media-file-name name] [-v | -version]
                        [-k | -encrypt-key file-or-path]
                        [-K | -encrypt-key-url <url>]
                        [-J | -encrypt-iv [random | sequence]]
                        [-key-rotation-period period]
                        [-n | -base-encrypt-key-name name]
                        [-encrypt-rotate-iv-mbytes numberMBytes]
                        [-l | -log-file file] [-F | -meta-file file]
                        [-y | -meta-type [picture | text | id3]]
                        [-M | -meta-macro-file file]
                        [-x | -floating-point-duration] [-q | -quiet]
                        [-a | -audio-only] [-V | -validate-files] [file]
 

 

  • Open a terminal window on your Mac.
  • Type “man mediafilesegmenter”at the command link prompt to get a full description of the usage of the tool.

          <command prompt>$ man mediafilesegmenter
 

  • An example of using the tool to segment a media file named “mymedia_hi.mp4”  is as follows-

        <command prompt>$ sudo /usr/bin/mediafilesegmenter -I -f mymedia_hi -f mymedia_hi.mp4
You will be prompted for the root password (which you must provide)
 
In the example, the media file “mymedia_hi.mp4” is assumed to be present in the current directory from which the command is executed. Otherwise, be sure to specify the path to the media file. The segments will be generated in a subfolder named “mymedia_hi” within the current directory.
 
<command prompt>$ cd mymedia_hi
<command prompt>$ ls
<command prompt>$
fileSequence0.ts           fileSequence14.ts         fileSequence6.ts
fileSequence1.ts           fileSequence15.ts         fileSequence7.ts
fileSequence10.ts         fileSequence2.ts           fileSequence8.ts
fileSequence11.ts         fileSequence3.ts           fileSequence9.ts
fileSequence12.ts         fileSequence4.ts           prog_index.m3u8
fileSequence13.ts         fileSequence5.ts

 
The fileSequence*.ts files correspond to the media segments which are MEPG2 transport streams. The prog_index.m3u8 is the playlist file corresponding to the segmented media file and specifies the media URIs to the segments.
 

  • The “-I” option that I specified in the example command will generate a variant plist file.  The variant plist file would be subsequently required to generate the variant play list file  as described in the next step. You don’t need this option if you don’t plan on streaming multiple encodings of your content.

         Assuming you are in the “mymedia_hi” folder, type the following to get the list of generated variant plist files.
 
<command prompt>$ cd ..
<command prompt>$ ls *.plist
<command prompt>$
mymedia_hi.plist

 

Generating variant playlist file :


If you do not intend to stream multiple renditions of the content , you can skip this step and proceed to the “Streaming the Content” section.

  • Follow the procedures specified in “Segmenting your encoded content” section to segment every encoding of the media content that you wish to stream.  For example, if you plan on supporting three renditions of your media content for high, medium and low network bandwidth conditions respectively, you will have to use the “mediafilesegmenter” tool to segment each of those renditions.

  • Use the tool variantplaylistcreator for generating the variant playlist file.

    /usr/bin/ variantplaylistcreator [-c | -codecs-tags] [-o | -output-file fileName]
    [-v | -version] [<url> <variant.plist> ...]

 

  • Type “man variantplaylistcreator” at the command link prompt to get a full description of the usage of the tool.

    <command prompt>$ man variantplaylistcreator
 

  • An example of using the tool to generate a variant playlist file named “mymedia_all.m3u8”  is as follows-

<command prompt>$ sudo /usr/bin/variantplaylistcreator -o mymedia_all.m3u8 http://mywebserver/mymedia_lo/prog_index.m3u8 mymedia_lo.plist http://mywebserver/mymedia_med/prog_index.m3u8 mymedia_med.plist http://mywebserver/mymedia_hi/prog_index.m3u8 mymedia_hi.plist
 

You will be prompted for the root password (which you must provide)
 
The URL that is associated with the prog_index.m3u8 files for each encoding corresponds to the URL of the webserver that will be used for hosting/streaming the media content.
 

  • The generated variant play list file “mymedia_all.m3u8” will specify the URIs to playlist files (prog_index.m3u8) corresponding to each encoding of the media file. The contents of the file (viewable using your favorite text editor) should be something like this 

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=87872
http://mywebserver/mymedia_lo/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=100330
http://mywebserver/mymedia_med/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1033895
http://mywebserver/mymedia_hi/prog_index.m3u8

 

Streaming the Content:

  1. Upload the variant playlist file (mymedia_all.m3u8 in our example) and ALL the sub-folders that contain the generated segments for every rendition of the media file to the web server that will stream the content. You do not have to copy the media files (eg .mp4 files) from which the segments were generated. You could host it on any regular web server such as the Apache Webserver or Microsoft's IIS. For instance, on an Apache server on Windows, you would copy all this to the “htdocs” folder. This would be something like this-  c:\Program Files(x86)\Apache Software Foundation\Apache2.2\htdocs.

  2. Typically you would need to make no changes to the web server in order to stream the content. In some cases, you may need to update the  webserver configuration file to add support for the .m3u8 MIME type . I had to do this for my IIS web server where I associated the .m3u8 extension with “application/octet-stream” MIME type. 

Note: If your needs are large scale, you would employ the services of a Content Distribution Network (CDN) such as Akamai to publish and distribute your content.

Accessing the Content from your iDevice:

  1. In order to access the streaming content on your iDevice, the media URL must point to the appropriate playlist (.m3u8) file. This would correspond to either the Variant playlist file if you support multiple encodings of the content (mymedia_all.m3u8 in our example) or the prog_index.m3u8 playlist file for the specific encoding of the content.

Example: http://<webserver>/<path to the .m3u8 playlist file>
 
If you do not have a streaming app, you can open the URL in the Safari browser on your device. If everything goes well, the stream should start playing on your device.
 

1 comment

 

This is probably one of the most commonly asked questions by folks looking to mobilize their business (probably right after what mobile platform to target).

While I have discovered a lot along the way from my own experience as a (native) mobile developer, I must add the disclaimer that this blog is also a result of discussions with a lot of smart people in this space. I thought it would be worthwhile sharing it to a potentially larger audience.

Definitions

 First , a brief definition of the two- [Mobile]Native Apps are mobile applications that can be downloaded and saved onto your mobile device from where they can be loaded to run natively on your device. [Mobile]Web Apps are mobile applications that are hosted on a remote server from where they are loaded and to run within a web browser environment on your mobile device.

The list below is by no means exhaustive. It is an attempt to highlight the major advantages of the two

 

Why a Web App?

 

                       1) “Develop once, Run everywhere”

 This implies that the web app is for most part platform agnostic. This has been widely touted as the selling point for web apps, however the statement is not entirely true. HTML5 is still in the process of standardization (http://dev.w3.org/html5/spec/Overview.html ) and as we know all too well, despite standardization efforts, ,there will undoubtedly, be variations in browser implementations across platforms. These variations will impact the behavior, performance and appearance of your web app on the various platforms. Still, while I cannot quantify this statement, one can infer that the development effort/cost will be lower than building native applications independently for each of the platforms of interest.

                      2) App is primarily “network data driven”

By this, I mean that the app communicates heavily with backend data servers for its various functions. Communicating large volumes of data across a bandwidth constrained wireless network is not practical (unless you have a cheap, unlimited data plan – if there is such a thing!). In this case, hosting the app in the network in the proximity of the servers will alleviate the problem.

                      3)Application developers want to “be in greater control”

Today, the fate of the apps is dictated (to a large extent) by the terms and conditions imposed by Apple App Store , the Android Marketplace or any of the other app storefronts. As an example, Apple’s “subscription model” imposed major restrictions on in-app purchases made from native apps  which led many app developers to remove the “Buy button” from their apps.  Web apps will allow you to bypass those restrictions allowing consumers to directly make purchases from their web apps. This provides developers the flexibility they need to deliver the desired service to their consumers without being encumbered by policies set forth by the application store owners. That said, while there isn’t a concept of a “web app storefront” today, one can envision that something like that would be in place when web apps become more ubiquitous. So it remains to be seen if there would be any restrictions that can impact the services rendered by web apps.

 Why a native app?

 

                      1) Performance, Performance, Performance!

This statement probably needs no further explanation. If performance is an important criteria, which is typical of  game apps, then native app is the way to go

                      2) Superior User Experience/ Interface

Native Apps leverage the hardware acceleration support for graphics available through specialized GPUs and use customized/optimized platform-specific  graphics libraries , thereby resulting in a vastly superior UI experience that is hard to match by web apps using JS/HTML/CSS. I earlier mentioned “Develop once, Run Anywhere” as an advantage for web apps- However, if UI is an important consideration for your app, then note that the  same “one size fits all” model will result in a sub-standard  user experience on certain platforms  and this would be unacceptable to users who are used to a particular level of user experience on a given platform.

                         3) Support for Remote Notifications

Most platforms provide some sort of remote notifications framework (eg- Apple’s PUSH Notification Framework, Android’s C2DM ) that allow registered apps to receive asynchronous from their application servers via centralized notification servers. Only native apps can register for push notifications. If this is a requirement for your app, then native apps are definitely a better fit. Alternatives for web apps like SMS or emails are not as seamless or compelling.

                     4)No Network Connectivity

If your app does not require network connectivity for its various functions, then offering it as a web app would impose that unnecessary requirement for it to run. Of course, HTML5 supports Application Caching that can be used to locally cache apps and run it even without a network connection. So this is probably not an issue, but the level of support may vary depending on the browser’s HTML 5 implementation.

                    5)Better Hardware Access & Control

Native Apps can access and control platform hardware resources like camera, accelerometers through native APIs exposed by the platform. This can be leveraged to build unique, compelling features into the apps. Although HTML5 is aimed at standardizing access to various hardware resources on the platform, the level of support is likely to be “inferior” compared to the options available to Native Apps – and by ”inferior” I mean that the platform vendors are more than likely to support access to a particular hardware  resource natively prior to supporting it on their browsers.  In some cases, the vendor may choose not to (for security reasons) provide access to certain hardware resources via their browsers. Besides, the level of hardware access support can vary across browser implementations.

In Summary..

There is a place for both types of apps out there. The choice greatly depends on the objective of the application and the targeted audience.

 

Cocoaconf is here!

Jul 27, 2011

2 comments

Finally, a technical/developers conference in the mid-west !

The  first Cocoaconf iPhone, iPad and Mac developer's conference, beginning August 12-13 in Columbus Ohio! There is an exciting lineup of talks by eminent speakers/authors. Its still not too late to register. Check out the details @ http://cocoaconf.com

Of course, I'm very excited about the conference being in my neck of the woods. What's even more exciting is that I won a ticket to the conference at the CocoaHeads meeting a month ago! Now, I've always been the person who is next to the person who wins, so this broke that jinx. 

I'll be there. Will keep you posted.