Ad-Hoc builds distributed over the air (OTA)

It is possible to share your test Ad-Hoc builds over the air, so testers won’t need to downlod ipa files and sync them via iTunes. Sometimes testers are having their iOS devices...

It is possible to share your test Ad-Hoc builds over the air, so testers won’t need to downlod ipa files and sync them via iTunes. Sometimes testers are having their iOS devices synced with computers not on their desks so it would be nice to download a version of the without a need to connect the device to the iTunes.

How to do that? It’s quite simple. Do normal steps to archive your app, and while you be generating new ipa file (on the save sheet) select “Save for Enterprise Distribution” at the bottom of the screen.

You need to type to informations there. First – the full path to the place on the network your file will be stored at, second – application name.

Generating OTA build

And voila! You’ll get to files – ipa itself and special plist file. What to do with that?

Put it on the webserver together with a HTML file like this

<html>
<body>
<p>Click <a 
href="itms-services://?action=download-manifest&url=
http://testingserver.com/1.0/myapp.plist">HERE</a> 
to install My App version 1.0 Beta</p>
</body>
</html>

Now, when the user will open the given page and click the link, safari on the device will understand that given link is acutallu an itunes action to install the application which manifest (the plist file you’ve generated) is linked under url attribute.

Simple, isn’t it?

Shadow performance

iOS and its programs is all about the looks. We’ve seen a lot of functional programmes previously. But this is iPhone that put a lot of focus on how the app...

iOS and its programs is all about the looks. We’ve seen a lot of functional programmes previously. But this is iPhone that put a lot of focus on how the app presents its data. One of the ways to make your views a bit more eye-candy is adding shadows.

Let’s say we have a table view that should have elements that drop a shadow in every cell. iOS SDK helps you with that. You simply set few parameters in superview of views you would like to see dropping a shadow and voila!

c.contentView.layer.shadowColor = [[UIColor blackColor] CGColor];
c.contentView.layer.shadowOffset = CGSizeMake(0, 2);
c.contentView.layer.shadowRadius = 5.0;
c.contentView.layer.shadowOpacity = 1.0;

You add a bit of the code and it’s done.

Or is it?

As long as you test it on your simulator everything looks ok. But the moment you’ll put it on a device a new problem will pop up. Your app is loosing its smootheness! If you will – in example add a shadow on elements inside a table view, scrolling a table view will become a nightmare!

Why does that happen? Isn’t it obvious? Calculating how to drop shadow is very CPU consuming and is done every time the view renders itself. We deal with a handset that’s slower than normal, stand alone computer that has a dedicated, high-performance GPU. But there’s a quite a simple way of fixing this. You could simply prerender the shadows – set it inside of the cell – push it to the background… and that’s it! Application regains it’s smootheness.

if (!c.prerenderedBackground)
{
    // There's no prerendered background yet - so
    // We configure view for shadow (like in version above:
    c.contentView.layer.shadowColor = [[UIColor blackColor] CGColor];
    c.contentView.layer.shadowOffset = CGSizeMake(0, 2);
    c.contentView.layer.shadowRadius = 5.0;
    c.contentView.layer.shadowOpacity = 1.0;
 
    // Now - we make a "screenshot" of that view
    UIGraphicsBeginImageContextWithOptions(c.contentView.frame.size,
                                           NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    [c.contentView.layer renderInContext:context];
    CGContextRestoreGState(context);
 
    UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    c.prerenderedBackground = [[UIImageView alloc]
                                      initWithImage:screenShot];
    [c.contentView addSubview:c.prerenderedBackground];
    [c.prerenderedBackground release];
    [c.contentView sendSubviewToBack:c.prerenderedBackground];
 
    // And now - disable shadow
    c.contentView.layer.shadowOpacity = 0.0;
}

I’ve made a simple app that implements the same table in three ways: no shadow, standard shadow and prerendered shadow. If you don’t believe me it really works – test it yourself ;)

Unit test results

Sometimes (according to Google – never ) one have a need to gather all results from unit tests. In example – to send them through the network. Why? Imagine that you...

Sometimes (according to Google – never :P ) one have a need to gather all results from unit tests. In example – to send them through the network. Why? Imagine that you need to report every unit test results to corporate server. Just to check for regressions… or something. I need it so my students can check “The Board” during the challenge.

Unluckily OCUnit given in XCode4 doesn’t seem to allow us to gather this kind of information. There is a solution though.

SenTestCase doesn’t have any methods that can return the results. What’s more – it is created and prepared for each test separately. That’s unfortunate.

The entry method that is called for each test is -(void)performTest:(SenTestRun *)aRun; That give’s us a hint when the test is actually triggered. But we still don’t know which one and how many of them are still left. But we can count the number of runs… information about the number of test methods in the class we can get from Class itself.

So we simply add following method to our test case:

- (void)performTest:(SenTestRun *) aRun
{
    static int performed = 0;
    static int failed = 0;
    static int totalTestCount = 0;
 
    if (totalTestCount == 0)
    {
        totalTestCount = [[[self class] testInvocations] count];
    }
 
    [super performTest:aRun];
    performed++;
    if ([aRun failureCount])
        failed++;
 
    if (performed == totalTestCount)
    {
        NSLog(@"Total tests %u failed %u", performed, failed);
    }
}

About time!

It took me a while to make this decission. I’m working with Cocoa for years. And I’ve started working on iOS from the day one – day when iPhone OS SDK beta...

It took me a while to make this decission. I’m working with Cocoa for years. And I’ve started working on iOS from the day one – day when iPhone OS SDK beta was release for the first time.

I was in my own developer heaven. I’ve connected my previous knowledge from embedded systems development with my knowledge (and yes – enthusiasm!) from Mac OS X. It worked!

Years passed and I’ve figured out that in most companies I’ve worked for I am the only iOS developer on site!

I understood that most of developers I worked with have a lot of trouble understanding how Cocoa Touch works and why it’s different.

I’ve started training courses, teaching people how to develop for iOS. But trainings are always very intense. And sometimes I just want to share with something with my students. Or work collegues. Thus – this page.

I’ll try to update it as often as I can giving you some hints how I solve everyday problems in Mac OS X and iOS development.