Tiny Mission Blog

I recently ran into an issue with a custom font I was using with a project. The label on UIButton was cutting off many of the letters at the beginning and end of the label, even though my button was very wide and very tall. After a lot of frustration, I finally determined that I was going to have to make my own button implementation.

You see, Apple (or whoever designed the UIButton class) decided to auto-calculate the width of the button’s label based on the reported width of the font letters. I came to this conclusion after a lot of research and a lot of conjecture. The issue comes up primarily with italic and cursive fonts. These fonts are designed to nest the letters for a nicer effect. The way they nest is that the font designer actually draws the letter intentionally outside of its calculated bounds. This allows two cursive letters to touch and other styles of letters to be closer together so that a letter like ‘f’ doesn’t look abnormally far away from a letter ‘t’.

The font letters designed to be outside of the box is so common that I cannot believe Apple would do such a thing as calculate the width of the label based on the letter width calculations. There is no way for you, the developer, to override this calculation to make that label wider. I won’t lie — I spent 3 days fuming at Apple for making this mess for me. And then I got down to business — subclassing UIButton.
Before: After:

In a lot of cases, simply placing a label with a transparent background over your button would be sufficient, and it probably makes more sense to do that if you can get away with it. However, I was moving these buttons around the screen and using the prebuilt button actions like touchUpInside, setHighlighted:, setSelected:, etc and I didn’t want to lose all of that by making a custom UIView that looked like a button. The answer was to subclass UIButton. I searched the internet quite a bit to make sure I was doing it right (I didn’t want to lose any of the code I’d already written that utilized UIButton) and a lot of posts said things like “you can’t subclass UIButton”, “you should make a category”, or plain old made it sound so complicated no one would want to try it.

I did subclass UIButton, it wasn’t that complicated, and it works very well in my application. Here’s the code:

@interface LetterTileButton : UIButton {
    UILabel *buttonTitleLabel; //This is the custom label so that I can calculate my own width
    UIColor *titleColor; //Remember the color of the label in case I call setHighlighted or setSelected manually
    NSString *buttonTitle; //Save the title for later reference, if needed
}
//Manual setter and getter for the font because for UIButton, the font is a property of the title label.  You could also override the UIButton methods, but this was better for my situation
-(void)setTitleFont:(UIFont *)font;
-(UIFont *)getTitleFont;
@end

@implementation LetterTileButton
//implement initWithFrame to instantiate your button class from code.  Use initWithCoder to instantiate from IB
-(id) initWithFrame:(CGRect)frame {
   if (self = [super initWithFrame:frame]) {
      self.backgroundColor = [UIColor clearColor];        
      //make the label and format it the way you want, add it as a subview to the button
      buttonTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, -5, self.frame.size.width, self.frame.size.height + 10)];
      buttonTitleLabel.backgroundColor = [UIColor clearColor];
      buttonTitleLabel.textColor = [UIColor blackColor];
      buttonTitleLabel.textAlignment = UITextAlignmentCenter;
      buttonTitleLabel.clipsToBounds = NO;
      [self addSubview:buttonTitleLabel];
    }
    return self;
}
//
- (void)drawRect:(CGRect)rect
{
    buttonTitleLabel.text = buttonTitle;
//update the frame of your label in case the button frame has changed
    buttonTitleLabel.frame = CGRectMake(0, -5, self.frame.size.width, self.frame.size.height);
}
//
//override all of the button methods you need and apply the formatting changes to your label
-(void)setTitle:(NSString *)title forState:(UIControlState)state {
    buttonTitle = title;
    buttonTitleLabel.text = title;
    [self setNeedsDisplay];
}
//
-(void)setTitleColor:(UIColor *)color forState:(UIControlState)state {
    titleColor = color;
    buttonTitleLabel.textColor = color;
    [self setNeedsDisplay];
}
//
-(NSString *)titleForState:(UIControlState)state {
    return buttonTitleLabel.text;
}
//
-(void)setSelected:(BOOL)selected {
    if (selected) {
        buttonTitleLabel.textColor = [UIColor lightGrayColor];
    }
    else {
        buttonTitleLabel.textColor = titleColor;
    }
    [self setNeedsDisplay];
}
//
-(void)setHighlighted:(BOOL)highlighted {
    if (highlighted) {
        buttonTitleLabel.textColor = [UIColor lightGrayColor];
    }
    else {
        buttonTitleLabel.textColor = titleColor;
    }
    [self setNeedsDisplay];
}
//
//my custom title font setter and getter
-(void)setTitleFont:(UIFont *)font {
    buttonTitleLabel.font = font;
    [self setNeedsDisplay];
}
//
-(UIFont *)getTitleFont {
    return buttonTitleLabel.font;
}
@end

And to implement the button, you can no longer use buttonWithType:, you have to use the alloc/init method:
LetterTileButton *letterTile = [[LetterTileButton alloc] initWithFrame:letterFrame];

And then you can use all of the normal property setters because you overrode them in your subclass. It’s actually not that difficult to subclass UIButton!

[letterTile setTitle:myTitle forState:UIControlStateNormal];
[letterTile setFont:myFont]; //this is my custom font setter

Alpha Release: Kara Web Framework

I’d like to announce a web framework I’ve been working on that uses the Kotlin language for the JVM. It’s called Kara, and while it’s still in the alpha stage, it has a ton of cool features.

Check it out at Github: http://github.com/TinyMission/kara

Tags: kotlin kara jvm
NSDateFormatter is Expensive

I’ve always heard vague assertions that NSDateFormatter is expensive, but never really paid much attention. But now I have experienced that expense first hand and wanted to share my concrete experience seeing just how expensive they are. I had code very similar to the following:

for (int i=0; i<150; i++) {
    //do some stuff...
    for (int k=0; k<40; k++) {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        df.dateFormat = @"YYYYMMdd";
        //do some more stuff
        NSLog(@"Some stuff: %@", [df stringFromDate:[NSDate date]]);
    }
}

This code took 5.5 seconds to execute. I was executing it up to 10 times, which made for almost a full minute of loading time for my view which used this information. Changing the code to look like this reduced the execution time to 2 seconds, which ended up about 20 seconds for loading:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateFormat = @"YYYYMMdd";
for (int i=0; i<150; i++) {
    //do some stuff...
    for (int k=0; k<40; k++) {
        //do some more stuff
        NSLog(@"Some stuff: %@", [df stringFromDate:[NSDate date]]);
    }
}

With a few more optimizations, I was able to reduce my loading time even further, down to 5 seconds. But with the simple optimization of reusing my NSDateFormatter, I was able to reduce my loading time by 60%. So use NSDateFormatter with caution and reuse it throughout your View Controller whenever possible.

Our Favorite Apps

Its hard not to fall in love with the devices and apps that surround this mobile ecosystem. We have the pleasure of being able to help companies articulate and deploy their app ideas, but we also get inspiration ourselves. We constantly use the best apps in our own personal and work lives. Many of Tiny Mission’s connections and capabilities come from the apps we use on a daily basis. Its cliche to say how much mobile technology allows us to transcend time and borders by making us more connected, but these tools have transformed our lives in ways that we could not have imagined.

I wanted to share our favorite apps for work and play. Apps that we use everyday and simplify our lives. If you are thinking about developing an application, think about how your favorite apps enhance what you do and are almost a subconscious part of your day. Also think about what our favorite apps aren’t. We don’t believe that using apps to market a company is appealing. Apps should never be just a glorified website or contact card. Apps should solve a need or create a solution to a problem. Let us know your favorites in the comments.

Work

Evernote

I use Evernote to take notes every time I walk into a meeting. I use it to log any interaction I have with a client or an employee. I can look back at that library of notes on any platform and any device, as everything is synced quickly. I have found referring to notes by location with the geotagging makes tracking my conversations so much easier. The search functions are fantastic, as I can put in a keyword and find relevant notes. It does not have a fancy pen function or the ability to annotate photos, but it keeps images, voice notes, and text in one place. Indispensable and best of all – free.

Skitch

This photo and web annotation app was just launched by Evernote. They go hand and hand with a shared login to keep what you “skitch” accessible in your notebooks. Skitch lets you easily annotate photos, maps, and web pages. Grab a quick url, write some notes, and share it. Working, I have used it to highlight and note design ideas from certain webpages. Cribbing what I liked and then sharing it with the team. I have also used it to shoot a quick photo and add some notes on changes. Its easy to be inspired by something but if you don’t take a moment to capture the “why” behind the inspiration you won’t know why you took the reminder.

iBooks

Not just a great e-reader, I use iBooks as a repository for all the pdfs I receive. The syncing is easy and the reader is quick. There are so many PDF readers and annotating apps but when speed and easy access is important you can’t beat the tool Apple has created.

Whatsapp

Used as the “iMessage” worldwide, whatsapp has turned into my messaging system of choice. Grown out of of the price gouging of text messaging, this uses the data connection on your phone to share messages across platforms. Android and Apple devices work using the same app. Its not free but you will easily save the SMS costs. You can set up group conversations quickly and customize nearly everything about the app. This blends the need of SMS with the speed of an online IM system.

Dropbox

Keep and share files anywhere. Again another cross platform gem that has matured into a perfect place to keep many different types of files. Easy to setup on a desktop you can have your most important files at hand. I have yet to upgrade to a pro account since space keeps growing and growing. Easy to share updated links.

Joinme

The magic of screen sharing across platforms. I have used this to do basic trouble shooting with clients. I have asked them to share their screen via the Joinme website and magically I can point out the clicks. The quick dial function lets you actually use the meeting code as a conference call code. If you haven’t tried this app on your device or computer simply launching the app will give you a million ideas on how to use it in your daily life. Amazing.

Splashtop 2 Remote Desktop

A fast and secure remote desktop app that supports full video on the iPad. Sometimes you have to get back into your computer and this is by far the best. Its so fast that on a stable connection you can what streaming video like hulu. Log in to your machine quickly and get a file you need.

Paper

Draw and sketch with a beautiful interface. Great for doodling out diagrams and charts. I have used this as a mini-whiteboard on my iPad during small one to one meetings with employees. The minimal interface and simple tools allow some really creative drawings. Sketches and doodles look great and you’re not bogged down with a million options. This isn’t some glorified paint program for the detailed artist. This is an app to get ideas out of your head and onto paper.

Apps that I’m trying to incorporate into my daily life:

Tapose is another all in one note and syncing tool. I find it to be too slow for real work but I see so much potential. It lets you collaborate on notes.
Onlive desktop has been a useful toy for using true spreadsheets. The office apps on the iPad and iPhone are excellent but sometimes you need tried and true excel.

You may note that I don’t share anything about a timecard or time management software. We have written our own that we use internally. I think most startups have created a time-tracker software to prove their worth.

Personal Apps I love!

Flipboard

If you have an iOS device you probably have flipboard. It’s a perfect news aggregator and my first stop when I want to see what is going on in the world. The magazine design works and it’s the best twitter reader out there. It’s the app that starts and ends my day.

NPR and NPR Music

Two apps to listen to NPR streams while working away on something else. NPR newsreader is an excellent way to browse articles. I use the app mainly for listening to radio programs.

Instamap

Check instagram photos on a worldwide map. Want to see what life is like in Portugal, just drop a pin and see the fun pictures that pop up. See local menus since most people use instagram like to share what they are eating.

Alien Blue

Redditors unite! Alien Blue is a third party Reddit reader that is fast and fun. Mindlessly click links as you see what the internet has to offer. I really like that you have two panels on the iPad that allow you to see the link. Never click the back button on your browser again.

Wikime

Simple app to check out what wikipedia articles are around you based on location. I have used it extensively for travel when I click and wonder where I am. Learn some history around you and it links to google maps so you can walk there. I would love to see this turn into a custom walking tour application.

“Ask a Nomad”http://itunes.apple.com/us/app/ask-a-nomad/id446302438?mt=8

You can ask localized questions about where you are traveling to and get a response from a local. It’s been a valuable tool for traveling and finding out baby friendly locations in cities. I’m sure the quality of result is based on the amount of users in the area, but I have loved the responses from major cities across Europe.

Toucharcade App

The list of games I play is enormous. I’m not ashamed to say the bulk of the Apps I have ever purchased are games. To find the best new games can be tough and this has been my goto site for some time. The new app links reviews and discussion boards. If you want to understand what people want from their applications dive into the discussion board and get raw responses from the most advanced users. They have a fun weekly podcast as well that you can listen to.

I hope you enjoyed the peek at my iPad and you can see the influence that great design, speed, and daily use have on making a great app. The list of abandoned apps is getting very long, so our goal is to make your app stick.

Tags: apps
TinyRss

A couple months ago, we had the need to implement RSS feeds in several apps we were working on. Upon surveying the existing options for parsing RSS on Android, we realized there’s no good solution. The de facto standard for Java RSS parsing seems to be Rome, but they apparently don’t support Android out of the box. There are rumors that Android support will be added at some point in the future, but that doesn’t really do us much good right now.

The rest of the results were people talking about how easy it is to roll your own RSS parser. This may be true, but I was hoping to find something that was a drop-in solution (like the awesome MWFeedParser for iOS). Not finding anything suitable, I decided to write my own.

Enter TinyRSS. It’s an Android library that contains a very fast SAX-based parser and a configurable ListView imeplementation to display the feed results. It’s easy to setup and configure, with overridable options in the Activity and completely customizable styles. There’s an example application included. Best of all, it’s Open Source. So, check it out on GitHub.

  

Tags: android rss
Icon Sizes and Guidelines for iOS and Android

EDIT: Updated for the new iPad retina display

Every time I have to make some icons for an app, I always have to go look up the sizes for each platform. So, I figured I’d make a post with the sizes (including actual-sized boxes, of course), and links to the relevant design documents from each manufacturer.

Apple and Google both provide guidelines for designing application icons, and it’s worth checking them both out. They have different approaches to icon composition, since iOS wants each icon to be inside a rounded-square box with a glossy highlight* and drop shadow, and Android encourages taking advantage of the alpha channel and using unique shapes.

* Technically, you can turn off the glossy highlight on your iOS home screen icon, but most developers seem to leave it on.

  Size 36px Ratio Uses
 
36px 1:1 Android ldpi (basically never used any more)
 
48px 4:3 Android mdpi (used on older phones and tablets)
 
57px 19:12 iPhone (non-retina display)
 
72px 2:1 iPad and Android hdpi (used on most modern phones)
 
96px 8:3 Android xhdpi (used on very new phones)
 
114px 19:6 iPhone 4+ (retina display)
 
144px 4:1 iPad 3+ (retina display)
Color Key:
Android Only
iOS Only
Android and iOS
Tags: ios android
Get Ready for App Submission

Here’s a quick list of the information to give to your developer so that they can submit your app. It has now been updated for iPhone 5 and the latest App Store requirements

 

  1. Company Name — If this is your first app, you have to choose your company name. This is the name that displays in the App Store for all of your apps and cannot be changed once you choose it.
  2. App Name — This is the name that appears for the app in the App Store.
  3. Display Name — This is the name that appears under the icon on the iPhone.  It can be the same as the app name, but is often a shorter version
  4. App Icon — a 1024px x 1024px icon that displays in the app store.  This can be the same image used as the app icon on the actual device
  5. Copyright  — something like “2012 Company Name”
  6. Marketing Description — This appears on the app store and is used to describe your app.  Use this space to explain what it does, who should use it, any subscription, payment, or login requirements.  Put the most important information at the top.  There is no limit on the length of this description. It can be changed any time, even after the app is in the App Store.
  7. Keywords — These are the terms that help people find your app in the App Store.  The limit is 100 characters, including commas and spaces.  There is no need to include the exact app name in the keywords, but a common variation of the app name might be handy. These can only be changed when a new version of the app is created and before it is reviewed.
  8. Category and Secondary Category — Determine which categories your app falls into.  The secondary category is optional.
  9. Price — How much do you want to sell your app for?
  10. Screenshots — Your developer can likely take screenshots, but they need to know which screens you want featured on the App Store.  To take screenshots yourself, hold the top button and tap the home button of your iOS device.  The screenshots will now be in the Photos app on your iPhone or iPad. Screenshots are required to be 640×920 or 640×960 for iPhone and 640×1096 or 640×1136 for iPhone 5. For iPad, they must be 768×1004 or 768×1024. All screenshots can be portrait or landscape

 

Here is a guest submission by one of our developers, Hahnemann. The background for this article is that we needed to show inline email attachments in our clients’ Outlook accounts. This was a long battle, as Outlook has some quirks regarding attachments that I find to be antiquated after having seen inline attachments with other email systems for the last 3+ years. Happy holidays and happy new year! — Bekki

The process of composing an email using iOS is fairly simple. The MFMailComposeViewController class provides a standard interface to compose and send an email as follows:

MFMailComposeViewController *email = [[MFMailComposeViewController alloc] init];
[email setToRecipients:[NSArray arrayWithObject:@"someone@somewhere.com"]];
[email setSubject:@"Your Subject"];
[email setMessageBody:@"Your message." isHTML:NO];
[email setMailComposeDelegate:self];
[self presentModalViewController:email animated:YES];
[email release];

If you want to include an attachment, you need to reference the attachment and send it inside a message to the class instance. Here is an example that attaches a file containing HTML:

NSString *html = @"<html><head></head><body>Some markup.</body></html>";
NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding];
[controller addAttachmentData:data mimeType:@"txt/html" fileName:@"markup.html"];

This works great, except for one problem. Email clients such as Gmail and Outlook will not display the attachment text inline. The attachment will be included in a preview pane for the user to open or select in order to display or download. This is a common feature used by most email clients to increase security and privacy.

The trick to make the attachment appear inline is to convert it to an image first, compose your email in HTML format, and attach the image instead. Obviously not all attachments can be converted to images (e.g. a SQL database) but our example contains markup that can be transformed to a JPEG or PNG when rendered inside a UIWebView.

Here’s how it works. First, you have to render the HTML inside a UIWebView that is hidden from the user:

NSString *html = @"<html><head></head><body>Some markup.</body></html>";
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 700, 300)];
webView.delegate = self;
webView.hidden = YES;
[self.view addSubview:webView];
[self.view sendSubviewToBack:webView];
[webView loadHTMLString:html baseURL:nil];
[webView release];

Next, you need to wait for the UIWebView to render the HTML before creating the image, or the image itself will be blank or incomplete. This is done inside the webViewDidFinishLoad instance method that is invoked by the UIWebView delegate when it finishes loading a frame. Notice we use here a performSelector that calls a separate method named composeEmail after a delay of one second, just enough time for the render process to finish before composing the email. The method needs the webView because this is where the markup is rendered:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [self performSelector:@selector(composeEmail:) withObject:webView afterDelay:1];
}

Finally, in composeEmail you create and save the image to your Documents app folder, before you attach it. Remember the email has to be in HTML format:

There are other recommended ways to do this, such as including images using Base64 encoding. This appears to work, but you also need control of the MIME standard in the code and unfortunately iOS does not allow this.

Top Reasons To Avoid Blackberry Development

If we ever decide to develop another Blackberry app, it will be for 3x the cost of the iOS and Android version, 3x the timeline, and 3x the heartburn medicine.  Here are my top reasons why I hate Blackberry development:

1) The simulators – There is a different simulator for every combination of device, OS, and carrier.  Do they really expect developers to do that much testing just because they can’t be bothered to create consistency between their products?

2) The devices – I can go on and on about these, but my biggest gripes are all of the permissions and settings that have to be manually set to use features like Wifi and databases.  Without a BB data plan, we can’t even use the GPS, which means a lot of $$ just to test our apps.

3) The code signing – Anyone who has seen Apple’s code signing process might think that it can’t get any worse.  But BB takes the cake again!  In order to test on a device, a developer has to request keys which take up to 2 hours to receive.  Then they have to be code signed against the BB server every time you build the app for a device.  This means that I have to enter my key password (once per Eclipse launch).  But then that means that their signing server must be online for you to get your work done.  All this is tolerable until you find out that they take their signing server offline for maintenance almost every evening, US time.  So if you don’t live in the US or if you program at night (like we frequently do), you are completely unable to test during those hours.  

4) The emails! – Oh the emails.  Every time this code signing process occurrs, RIM sends me a confirmation email for every single .cod file that was signed.  For illustration, here is my trash bin just from today.  Yes, that number says 500.  Supposedly, this is for security and can’t be disabled, but I say that if I auto-filter these all to my trash bin, the security has been rendered moot.

5) The documentation – Most of the documentation reads like it was written by a marketing person, not a developer.  Case and point, this article that supposedly tells developers how to upgrade their apps to OS 7: http://devblog.blackberry.com/2011/06/blackberry-7-simulators/ It is so vague and high level that it isn’t actually helpful in any way.  The documentation that is actually written by a technical person is so short and terse that I generally have to google half of the instructions to get the actual instructions.

6) The OS’s – I don’t even know where to begin.  I can’t build an app for OS 6 and have it work reasonably well in OS 7.  I have to build two apps and submit them to both versions of App World in order to get to all of the users.

7) The online support – I guess I’m spoiled by how much online material, support, forums, tutorials there are for iOS and Android, so the lack of options for BB are shocking to me.  There is some guidance on the BB forums and on stackoverflow, but it’s so contaminated with posts from 2009 that are completely irrelevant (due to the complete lack of backwards compatibility with older OSs) that it almost isn’t worth it.  It’s really apparent that there aren’t too many BB developers out there.

8) The User Interface – BB has done a great job of convincing us to use the simplest user interfaces, which are completely unimaginative and pretty ugly compared to iOS and Android.  I’m sure all the users who like the joystick/mouse of the BB appreciate having boring lists of information that are easy to scroll through and select, but there is so much more possible.  But this hasn’t even addressed my rant about the UI.  My real issue is that they have to be build completely in code.  There is no UI layout builder to quickly put together a pretty UI.  Since everything is done by hand in code, it takes a long time, a lot of guess and check, and doesn’t encourage being creative.

9) Not Mac OS X compatible – This might not be a huge deal for some developers, but I prefer to have just one computer and that happens to be a Mac.  Eclipse is Mac OS compatible, Java is Mac OS compatible, but for whatever reason, the Blackberry Plug-In for Eclipse isn’t.  There is a Mac beta out now, but it’s buggy and doesn’t work well with simulators.  I don’t have high hopes for it based on the quality of the rest of the BB development tools.  I use a virtual machine at this point, and it does the job. 

The entire Blackberry development environment feels like it was hacked together.  Nothing is cohesive and nothing “just works”.  Every step of the way is a struggle of troubleshooting and figuring out what is unhappy now and then figuring out how to fix it.  I wish that my time was being spent debugging and improving my apps, but instead I deal with “SD Card Missing, can’t debug” errors.

Tags: blackberry
iOS5 Upgrade Nightmares

Like most iOS developers, we have been spending a lot of time rushing around getting all of our apps ready for iOS 5. It has been “trying”, to put it mildly. Simple things that we’ve taken for granted ever since iOS 3.0 suddenly don’t work, but leave very little debugging trace for us to follow. After countless hours researching and debugging, and now that the NDA is gone, here’s the list of biggest issues we’ve found:

Modal View Controllers

self.parentViewController is now nil in iOS5, so any code like this [[self parentViewController] dismissModalViewControllerAnimated:YES]; will no longer work. In iOS5, change this to [self dismissModalViewControllerAnimated:YES];, but if you want to maintain backwards compatibility with iOS 4.x, you will need to add a conditional because this won’t work in the older versions.

More Modal View Controllers

In iOS5, suddenly some of my modal view controllers weren’t presenting at all. They worked great in older iOS versions. It turns out that iOS guidelines don’t want model view controllers to be presented in viewDidLoad or in viewWillAppear, but this was not enforced in pre iOS5 versions. I guess I got pretty lazy in this respect and had a few modals presented in viewDidLoad. Especially in instances where I wanted to show a login or loading screen.

After moving all of these [self presentModalViewController:ctrl animated:NO]; calls to (void)viewDidAppear:(BOOL)animated, they now work. Sounds great, but there’s still one more step — the benefit of using viewDidLoad to present these is that it’s only called once when the view is loaded, but viewDidAppear is called (as you can guess) every time the view becomes visible. So for this to work, make sure to set a flag that makes sure the modal view controller snippet only gets called once. For me, it looks like this:

if (!viewLoaded) {
    LoadingViewController *ctrl = [[LoadingViewController alloc] initWithNibName:@"LoadingViewController" bundle:nil];
        [self presentModalViewController:ctrl animated:NO];
    [ctrl release];    
    NSLog(@"presented");
    viewLoaded = YES;
}

View Lifecycle Changes

I ran into this issue while firefighting some major customer complaints, so the exact process I took to solve this isn’t perfectly clear in my brain. But here’s the bottom line — After (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions, the order that viewDidLoad in the root or first view gets called has changed. In iOS5, viewDidLoad gets called right away, where in older iOS versions, (void)applicationDidBecomeActive:(UIApplication *)application got called before viewDidLoad. This probably won’t affect too many apps, but we happened to be checking for updates there and were taking action in viewDidLoad based on the results. Once again, this was tough to solve while maintaining backwards compatibility.

UIWebView Issues

This one just came up this morning, where the app crashes after I load a PDF file into a UIWebView and then pop the view controller. Once again, no issues pre iOS5, and this error has the joy of no stack trace and no debugging information. I’m still researching the issue and will update this post when I figure it out.

Update

The webview issue seems to have been a fluke with the debugger. If I remove the Break on all Exceptions breakpoint, it functions fine. Before removing that breakpoint, I tried pressing play again after it stopped at the exception. Go figure, it would continue running the app without issue. After some additional research on Stack Overflow, many others had this exact issue and were all able to solve it by removing the exception breakpoint.

Tags: ios

As a Windows/Linux user who’s spending most of his time on OS X these days, there are several little features that I miss. One of them is the ability to create a new file from directly within the file browser (i.e. Finder). Well, I guess I’m not the only one, as I found this awesome little script called “New Text File Here”:

http://wisser.me/software/#NewTextFileHere

Just download the .app file, start editing your finder toolbar, and drag the app into an empty space. The current version prompts you for a file name and automatically opens it in a text editor after it’s created. Great stuff!!

Tags: os x
Link to the App Store from Within Your iOS App

Linking to the App Store from directly within your application is a great way to let people know about your other apps or to upgrade from a free version to a paid version. Doing this is actually quite simple. Just put a button in your app and link the action to the following code:

-(void)purchaseFullVersion {
    NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.com/apps/appname"];
    [[UIApplication sharedApplication] openURL:url];
}

If you want to link to all of your apps:

-(void)viewAllApps {
    NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.com/apps/developername"];
    [[UIApplication sharedApplication] openURL:url];
}

Tags: ios
Rendering to a PDF on iOS using UIKit

For some reason, this seems like a difficult thing to google for and can often lead to people doing things the wrong way, so I’ll show how simple it is to do PDF rendering in iOS.

The problem: you have an iPhone or iPad app that does some custom drawing inside a subclass of UIView. Now you want all of your awesome graphics to be exported to a PDF so you can either archive it or share it with people who don’t have your app.

Unfortunately, a lot of people google around for a solution and end up finding some really convoluted examples using CGPDFContextCreateWithURL and making CFDictionaries. While you may be able to come up with a working solution using the CF* and CG* functions, it’s not much more complicated than most people need.

Luckily, UIKit has some very handy helper functions in UIKit for doing exactly this. Assuming you’re insde a subclass of UIView that does rendering in it’s drawRect method, here’s how you generate a PDF called fileName at path:

NSMutableDictionary *pdfDict = [[NSMutableDictionary alloc] init];
[pdfDict setValue:fileName forKey:(NSString*)kCGPDFContextTitle];
[pdfDict setValue:@"Author of the PDF" forKey:(NSString*)kCGPDFContextAuthor];
[pdfDict setValue:@"App that created the PDF" forKey:(NSString*)kCGPDFContextCreator];
UIGraphicsBeginPDFContextToFile(path, 
    CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height), 
    pdfDict);
[pdfDict release];
UIGraphicsBeginPDFPage(); 
[self drawRect:self.bounds];
UIGraphicsEndPDFContext();

It’s that simple. UIGraphicsBeginPDFContextToFile creates a PDF context and sets it as the current UIKit context. Thus, all rendering operations on the current context will be directed to the PDF instead of the screen, until you call UIGraphicsEndPDFContext. The result is a PDF generated with native drawing commands, often much smaller yet better quality than an image capture of the view.

NOTE: If you’re rendering text in your UIView, make sure you use text rendering methods like [@"my string": drawAtPoint:] instead of placing UILabels over the view. The labels won’t be rendered to the PDF.

Tags: ios
Custom view class in MonoTouch

When making user interfaces in MonoTouch, as with anything, it’s often desirable to create a custom view class to display your content to the user. When using MonoTouch and Interface Builder, this is as easy as:

  • Add a UIView to your interface by dragging over the View item from the library
  • Go to the Identity tab of the properties panel and change the Class field to the name of your custom class.
  • Add your class to the project and make sure it inherits UIView or one of its subclasses.

I’ve run into a minor problem doing this, but reading around the internet it seems like it might not happen to everyone. If you get an error like:

Unknown class in Interface Builder file.

you simply need to add a MonoTouch.Foundatoin.RegisterAttribute to the class definition, like:

[Register("MyView")]
class MyView : UIView { ... }

Tags: monotouch ios

Last weekend we got bored and threw together a HTML5/Javascript-based online button generator. It’s called TinyButtonator, and it lets you define the buttons size, border, rounded corners, and a variety of stylized gradient background. It’s written in Javascript and uses the HTML5 Canvas API to do the rendering, all client-side. The buttons can be exported as PNG images with transparent backgrounds. You can also save the button as a permalink to bookmark or send to someone else.

There are a lot of similar websites out there, but none of them quite fit our needs. So we ended up spending a ton of time messing around in Photoshop or Inkscape making simple button images. We want something simple that looks nice, and they’re always a bit different. TinyButtonator gives us exactly that. It’s totally free, so go ahead and try it out!

Ad-hoc Distribution for iOS

Below are instructions for installing an application on your iOS device using Ad Hoc Distribution. The process is tricky the first few times you attempt it, so follow the instructions very closely. Once you’ve done it a few times, it gets much easier. There are three sections to this article:

  1. The first time you install your application onto your iOS device
  2. Installing an update to your existing iOS application
  3. FAQ — Or, Frequently Encountered Issues

The first time you install your application onto your iOS device:

  1. Make sure you have given your iOS device UDID to your developer
  2. The developer will send you a mobile provision file and an ipa file containing the application
    1. Many email programs don’t allow ipa files to be emailed, they may choose to post it somewhere for your to download as opposed to emailing it
    2. Save both the application ipa file and the mobile provision file to your computer in an easy to find location, such as your desktop
  3. Launch iTunes
  4. Drag the mobileprovision file into the left pane of iTunes under the Library section
  5. Drag the file called app_name.ipa (where app_name is the name of the application) into the left pane of iTunes under the Library section. You will see the mouse turn into a small plus sign when you hover over the Library section. This indicates you are in the correct place.
  6. Plug in your iOS device and select it from the left pane in iTunes
  7. Navigate to the Apps tab (along the top of iTunes) for your device and verify that the application is in the list and has a checkmark next to it. The app will have a white icon next to it in iTunes — the real icon will be present on your device.
  8. Press the Sync or Apply button at the bottom of the iTunes window
  9. Launch the application on your iOS device
  10. If you encounter any problems, check out the FAQ below or contact your developer directly

Installing an update to your existing iOS application:

  1. Delete the existing application from your device
    1. To do this, press and hold down on the application icon on your device until it shakes and a small X appears
    2. Tap the X, and confirm that you wish to delete it
  2. Did the developer send you a new mobileprovision file?
    1. If yes, save the mobileprovision file to your computer in an easy to find location, such as your desktop
    2. Drag the new mobile provision file into the left pane of iTunes under the Library section
    3. When asked if you wish to overwrite the existing file, press the Yes button
  3. Save the application ipa file to your computer in an easy to find location, such as your desktop
  4. Drag the file called app_name.ipa (where app_name is the name of the application) into the left pane of iTunes under the Library section. You will see the mouse turn into a small plus sign when you hover over the Library section. This indicates you are in the correct place.
  5. Plug in your iOS device and select it from the left pane in iTunes
  6. Navigate to the Apps tab for your device and verify that the application is in the list and has a checkmark next to it. The app will have a white icon next to it in iTunes — the real icon will be present on your device.
  7. Press the Sync or Apply button at the bottom of the iTunes window
  8. Launch the application on your iOS device
  9. If you encounter any problems, check out the FAQ below or contact your developer directly

FAQ — Or, Frequently Encountered Issues

“The application was not installed on the because the signer is not valid.”

  • Verify that you have dragged the mobile provision file into iTunes.
  • Verify that you are attempting to install the application onto a device that has been authorized by your developer. Each device must be registered to install the application.
  • If the mobile provision profile was issued more than 6 months ago, verify with the developer that it has not expired.

“The application was not installed on the because it requires a newer version of iOS software.”

  • Many iOS features are only compatible with newer iOS versions, and are not backward compatible. Verify with your developer what minimum iOS is required for your application.

“You can’t open the application because it is not supported on this type of Mac.”

  • Did you double click the application icon? If so, OS X attempted to open the application as a Mac application. Instead, drag the application icon into iTunes.

It still appears that the old version of the application is on my iOS device

  • Delete the application from your iOS device, following the instructions in the “Installing an update to your existing iOS application” section, item number 1
  • Continuing through those instructions, reinstall your application.
Tags: ios ad hoc itunes
Third Party Development Tools

Andy and I have been experimenting with MonoTouch on a few projects. For the most part it has been really good, especially for a few C# developers like us. However this week, XCode 4 came out and broke the link that MonoTouch uses with Interface Builder. I’m sure that the MonoTouch team is hard at work fixing this issue, but I was planning to submit one of my apps this week and can’t (easily) update one of my UI screens without going through a lot of trouble re-installing the old version of XCode. Until MonoTouch fixes this issue, I will have to spend a lot of time looking for workarounds.

Third party tools can be great, but remember that there is always the risk of an inconvenient update being released!

Tags: monotouch ios
NSFetchedResultsController and EXC_BAD_ACCESS

In apps that use Core Data and UITableView, it is very likely that you are also using NSFetchedResultsControllerDelegate to update the table view automatically. This feature is incredibly useful, but I ran into a strange issue with it. After a lot of searching and experimenting, I found a solution. Here it is for you in case you run into the same thing with one of your projects.

Cause: Two views that perform a fetch request on the same entity in your database, and both implement NSFetchedResultsControllerDelegate.

Result: After making an update on one of the table views and attempting to save the managed object context, you receive EXC_BAD_ACCESS, with very little information.

After setting NSZombieEnabled YES, I was able to see this message in the console:

  • -[MyViewController controllerWillChangeContent:]: message sent to deallocated instance

What was interesting to me is that I wasn’t in “MyViewController”, I was actually making the save in “MyOtherViewController”, but the change was being caught by the controllerWillChangeContent: method in the other view controller.

Solution: Buried deep within the Core Data programming guide the simple solution was to be sure to always set fetchedResultsController to nil after the view disappears. I was releasing it in the dealloc function, but that wasn’t enough — it needs to be set to nil. To make sure that it gets set to nil right away, I implemented viewWillDisappear: and put the code in there. Problem solved!

-(void)viewWillDisappear:(BOOL)animated {
    self.fetchedResultsController = nil;
}

Cross-platform Development Revisited

Awhile ago we spoke about using web apps with native wrappers as a good way to get your app to the widest audience over a large number of devices. This is done by creating a Javascript application and wrapping it in a native application using a web view for the specific platform. To store data and user settings in the application, use HTML5’s sessionStorage. This is where some of the issues with cross platform development come in.

Not all smart phone browsers have implemented HTML5 compatibility. For instance, Blackberry just started offering it in their devices running OS 6.0 and higher. At the time of this writing, Blackberry was still shipping devices with OS 5.×. This means that 90+% of the Blackberry devices won’t be able to run your application. In addition, Windows Phone 7 does not enable HTML5 in their native browser. So you can see that there are already a few snags in the “silver bullet” idea of cross platform development.

We just wrapped up a large cross-platform project, which is why I’ve chosen to revisit this topic now. This particular project involved accessing a database through web services, modifying data on the user specific device, and syncing that data back to the server. Other features include the ability to send an email through application and view videos and websites.

Our original plan was to have 99% of the application live in the Javascript code, with native wrappers for the iOS and Android platforms and a web URL for all other platforms. We quickly ran into issues with this when the iOS browser wouldn’t display several icons and toolbars in the jQuery Mobile template that we chose. After a lot of searching, we finally decided to implement the Tab Bar natively for iOS and Android. This was our first step toward making the application more native than originally planned.

The next issue we ran into was that the jQuery code couldn’t force the native app to change tabs. So we implemented several catches in the native code where, depending on which tab they were in, where depending on the user’s input, we would navigate and drive the application to a certain state or page, or ask another page to refresh. Already, the native code is getting more complex, and there is a lot of specific communication that was required between the jQuery and native code.

Our application required a user to log in before using it, and this created another spot where we chose to have the native code take over. This was to primarily to create a more simple and intuitive user experience. Instead of loading the login page into one of the tab views, we chose to put it into a modal view, one that took up the whole page and covered up the tabs. The native code had to catch the login request and reroute it to a modal view. Once the user logged in, the modal view was dismissed and the tabs were now visible.

Similar things came up when we wanted to launch the email client and select other configuration preferences. Many selections the user made in one tab required the view in another tab to refresh, but there was no way for the jQuery to do this directly, forcing us to perform the refresh within the native code. As we progressed through the project, there were more and more issues with the different platform browsers that we had to handle by adding to the native wrappers and adding more code to the jQuery to check for these situations.

Once the project was finished, the ratio of native code to jQuery was about 30/70, with most of the code being platform-independent. The 30% was still far more than we expected to have to duplicate on each platform. However, the app works well and we are very happy with the way it turned out. The biggest benefit to going with javascript on this application is that we built in a way to update the javascript code over the network without having to release a new revision of the native code. With the long iOS approval process and the tight timeline we were under, the remote updating ability was invaluable.

Cross platform worked well in this situation, but it is far from the magic solution that many assume. The next time someone asks us to make a cross platform application for them, we will be well armed with the pros and cons and the true cost (due to the 30% native wrappers) and will be able to help our client determine if this is the best option for them.

Why We Don't Buy Ideas

Periodically, someone will call us to ask if we’ll buy their app idea from them. We always say no, although we have entered into partnerships with several clients whose ideas we really liked. I never had a specific reason for saying no, beyond the vague idea that paying someone for an idea and then doing all the work myself seems silly.

I just read Rework by Jason Fried and David Heinemeier Hansson, the founders of 37Signals, and they summed up my vague idea better than I ever could have. The authors advise us to go make something, that an idea alone is basically worthless because everyone has one. They use the specific example of eBay — it doesn’t matter how many people thought of the eBay idea, it matters that the founders of eBay actually did something with that idea. Everyone has ideas, but what makes a great product is executing on that idea.

The authors go on to explain that executing on your own idea is the best way to create a great product. This is because you are passionate about the idea, you know why you need the product or how it will make your life better. They call it “scratch[ing] your own itch”. Another person cannot see your idea — the layout, the flow, the users, etc — the way you can. But it goes further than that. Most great ideas come from a specific area of expertise or domain knowledge. The value in that case isn’t in your idea, it’s in you. It’s in the expertise and vision that you bring to the table, the idea is empty without the wealth of knowledge from the person who came up with the idea. When we develop an app for a client, it’s the client driving the look, feel, and features of the app throughout the process.

That’s why we don’t buy ideas.

Tags:
Core Data - Seed Data In Your App

Most of our applications are data-driven, either from a local data source within the application, or downloaded to the application from a database on a server. One great way of getting data into an application is using an XML document. But the iOS XML parser is slow! We’ve had a few applications with fairly complex data models take over a minute to complete parsing. Since a one-minute loading time is completely unacceptable, we’ve implemented a few different strategies for speeding it up.

Applications that get their data from a server can either stream the data or save it locally to be referenced later. We generally tend to allow the data to be saved on the device so that our clients’ apps will be more useful to their users when network access is flaky or non-existent. Depending on the web service, we download the data in XML or JSON format. I prefer to then load the data into a Core Data sqlite database, especially if the user is going to be modifying or adding to the data. Core Data can be a pain sometimes, but it is really fast, and manages a lot of things for us behind the scenes.

In order to improve the initial user experience, we often “seed” the application bundle with an initial data set. This way, the user can use the app right away, regardless of network connection and data-syncing time. We could seed the app with an XML file containing the data, but like I said, it is slow! My favorite thing to do is actually to run the XML parsing in the iOS Simulator to generate a sqlite database from the seeded data set, and then include that database into the bundle. This bypasses the initial parsing issue and gives a great user experience. The user won’t notice any loading time, and the application will perform fetches to retrieve the data at the appropriate time.

Here’s how to do it:

  1. Run your app with the XML parsing in the simulator, loading the data into your Core Data database.
  2. Navigate to the Documents folder for your simulator’s files — \Library\Application Support\iPhone Simulator\Y.Y\Applications\XXXXXXXXXXXX\Documents\AppName.sqlite
    1. Where Y.Y is the iOS version number you are testing (currently, the latest is 4.2)
    2. Where XXXXXXXXXXXXXXX is the random number assigned to your application in the simulator — click through the list of these until you find your app inside
    3. Where AppName.sqlite is the name of your database (likely the same name as your project)
  3. Copy the sqlite database into your project folder
  4. Go into XCode and add that sqlite database to your project
  5. In the persistentStoreCoordinator method, either in the app delegate or root view controller file, add the following code to copy your database from the bundle to the Documents folder:

NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"AppName.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
    NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"AppName" ofType:@"sqlite"];
    if (defaultStorePath) {
        [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
    }
}
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

And that’s it, now you’ve seeded your app with your most recent data to avoid downloading and parsing data when the user first uses your app.

Tags: ios core data
Common Mobile App Architectures

I just got back from giving a presentation on mobile applications for business at the Apple Store Ridgedale. I discussed common app architectures for mobile applications and the required systems for each. I thought I would post them here for you all to see. Enjoy!

Tags: ios android
Tips for Getting More Downloads

You have come up with the best app idea ever, but you still need to get people to download it and try it out. Here are a few tips.

Make it free

This seems counterintuitive, since you were planning to make $1M from this app, but in my experience, free apps get downloaded at least 10x more frequently than $0.99 apps. There is no risk, so people will download it, try it out, and give you feedback so that you can make your app better. Here is a comic by The Oatmeal describing this phenomenon. In addition, the order of apps displayed in the App Store is a combination of number of downloads and rating, so having a free app with a lot of downloads will get you much more publicity.

Put ads in it

Contrary to popular belief, people do periodically click on ads. Especially people who are conscious of the fact that you need to pay your bills in spite of your app being free. If you feel like your app is one that people will use over and over again, like a game, this strategy is more likely to be successful.

Make a pro version

Use your free app as a teaser, and if people like it they will pay to upgrade. Your pro version should have additional content, and/or remove the ads.

Use In App Purchase

This is similar to the free/pro app concept where you give the user some content and allow them to purchase additional content through In App Purchase. This strategy has additional cost and overhead because you have to set up a hosting service, like Urban Airship, for your additional content and your developer has to add the code to your app. But it has benefits in the long run for giving your users easy access to new and updated content without having to modify the code for your app.

Make it a Universal App

A Universal App is one that has a specific user interface for the iPhone/iPod platform and another for the iPad platform, but all in one application. Apple gives more prominent placement to Universal Apps in the App Store, and users with both devices will appreciate being able to use your app from anywhere. All iPhone apps can run on the iPad by default, but they look kind of silly running in iPhone size on the large iPad screen. The iPad provides such a rich user experience, that it is worth the extra investment to optimize your app user interface for the iPad platform.

Contact local tech blogs

Many tech blogs like to write articles featuring what local small companies are doing with the latest technology. This is a great way to get some free publicity and some extra Google hits!

Have some other tips that worked out great for you? Write us and let us know!

Tags: ios android
iPad As Your Primary Laptop

I keep telling people that if I wasn’t a programmer, my iPad would be my laptop. Think about it: what do you do with your laptop? Everyone I asked (this wasn’t a statistically significant sample) says that they surf the internet, check email, watch Hulu/Netflix/movies, and upload pictures to their Facebook accounts. Basically, it’s their fun couch computer. My assertion is that my iPad does all of those things better than my laptop (or at least equally well). With the added bonus that I actually like reading books on my iPad.

Surfing the internet is downright obnoxious on a laptop — especially while I’m sitting on the couch and the trackpad is right up against my stomach. On my MacBook, the multi-touch scroll helps, but it’s still not ideal. On my iPad, I touch the screen to scroll where I want and pinch the things I want to zoom in on. I directly press the links instead of moving a mouse cursor all the way over. And the iPad fits on my lap better.

Typing emails on my iPad isn’t bad at all, because I generally don’t write dissertations in my emails and reading through emails is a breeze. I sync my photos to my iPad through iPhoto, but I can also connect my camera directly to my iPad (super handy while on vacation!), making emailing photos and posting pics of how much fun I’m having very convenient. Who needs a laptop for that?

While I was overseas for a month, I survived by watching TV shows and movies on my iPad that I bought on iTunes, Handbraked, and streamed on Hulu+, in addition to reading books that I bought using the Kindle app and the iBookstore app. I would call it a lifesaver for me. Yes I could have done most of that on my laptop, and brought some paperbacks with me, but holding a laptop sideways while laying in bed watching a movie isn’t very pleasant!

Basically, the only thing I use my laptop for these days is programming. And writing this article. :-)

Tags:
The Choice Between Netbook and Tablet

Netbooks filled a very specific niche a few years ago: small, cheap, portable computers. But they do this in the worst way possible, where everything is traded away just to have a small form factor computer. I hate doing anything on a netbook: typing on the tiny keyboard is not good for writing long papers. The tiny trackpad is terrible for playing games. And the tiny dim screen is awful for surfing the web and watching videos. So why would anyone want one ?

Enter the tablet device, specifically the iPad — although there’s plenty of competition gathering steam. The tablet has a big, bright touch screen that can be manipulated directly to optimize the interface for your specific task. It is a dream for surfing the web because it’s easy to scroll through content and zoom where needed. Videos look great on the screen, and the gaming experience is very pleasant. The biggest downside to tablets is the lack of a hard keyboard, which makes typing large quantities of text fairly annoying. But even this can be solved with a stand and a bluetooth keyboard.

Someone in the market for either of these devices probably isn’t planning to do any hardcore programming or video editing anyway, so which device is better? The biggest advantage to the netbook is that it uses a standard computer operating system, making it flexible enough to run all your standard applications without worrying about compatibility. However, the tablets have applications designed specifically for them, making the user experience much more tailored.

For my $500, the money is far better spent on a tablet because the overall experience is far more polished. It was specifically designed for its tasks: internet, watching videos, playing games, reading books — and performs the tasks wonderfully. The netbook was a good stop-gap between a 13” laptop and a tablet, but its time has passed.

Tags: ipad
iOS Development Changes For Small Businesses

Here at Tiny Mission, most of our clients are small businesses. We have found that small businesses have some amazing ideas for applications. These applications are usually for internal use, to make their business more efficient or to give them a competitive advantage over their competitors. These applications are not meant for App Store distribution, but for use inside the company on internally-owned iOS devices.

Until recently, internal distribution of iOS applications for small businesses has been a very difficult task. Small businesses with fewer than 500 employees were excluded from the Apple Enterprise Distribution program and forced to apply for a standard corporate account. The corporate account is not tailored for proprietary in-house distribution — it is intended primarily for App Store distribution. The enterprise program is specifically for in house distribution of applications; in fact you cannot submit an application to the App Store with the enterprise program.

Prior to October 2010, the only way to have internal distribution for a small business was to use Ad Hoc distribution. This is problematic because the business is limited to a maximum of 100 devices per year, the Ad Hoc provisioning profiles expire every 6 months and have to be regenerated by a tech-savvy person, and every time a new device is added to the company or a new profile is generated, the application itself has to be recompiled. Recompiling an application generally requires a developer or very tech savvy person, and has many risks if an unqualified person attempts it.

What does “100 device limit” actually mean?

Before talking about the recent changes that Apple has made, I would like to expand further on the limits of Ad Hoc distribution. 100 devices per year means just that, if one of your 100 devices breaks and has to be replaced that’s too bad. You’ll have to delete the broken device from your account and wait a year before adding the new device. If you add a device but accidentally mess up the device identification number (as I have seen happen to a few clients when they try to hand type the number instead of copying it), that’s too bad. The mistaken device ID still counts against your 100 device limit.

So you broke one device and successfully added a new one to your account. The next hurdle is getting this device authorized to run your internal application. To do this, you (or your developer) will need to log on to your account and regenerate your mobile provision profile to authorize the new device. Then download the new profile and recompile your internal application for distribution with the new mobile provision. This is the same procedure required when your Ad Hoc mobile provision profile expires every 6 months. For most small businesses, this is a task that puts a big burden on their lean staff. In general, most of our clients ask us to take care of this task for them.

The new Apple Enterprise Developer program

Apple just announced that they have expanded the Enterprise program to all companies from 1 employee to infinity employees. This is great news for our small business clients who are making internal applications, as they can now compile the application once and distribute it along with the license to all of their employees and internal devices without the hassle of limited devices and difficult, confusing installation processes. Enterprise offers additional benefits like wireless syncing and device cloning, which will all make maintaining your internal devices much easier. We are very excited to help our clients set up their enterprise accounts to make the application distribution process more seamless for them so that they can focus on what’s important: innovating for their clients.

Tags: ios
How To Locate Your iOS Device UDID

As we develop applications for our clients, they generally want to test the apps on their own iPods, iPhones, and iPads. In order to do this, we have to register the device’s UDID with the developer account to authorize the application to be installed on a specific device. Follow these simple instructions to get us your UDID:

  1. Plug your device into your computer.
  2. Launch iTunes
  3. Select your device from the left pane in iTunes and navigate to the Summary Tab
  4. Click once on the S/N (Serial Number) field, and it should change to a longer number called Identifier
  5. Now press Cmd+C (Ctrl+C on Windows). NOTE: The numbers will not highlight, even if you click-drag across them.
  6. Paste the numbers into an email to your developer (Cmd+V, Ctrl+V, or Edit→Paste)

Special note, typing the characters in by hand can often lead to incomplete or incorrect UDIDs being sent to your developer. Use the computer’s copy function to ensure accuracy, prevent errors, and be sure that you can get your application for testing as fast as possible!

Tags: ios udid
HTML 5 Texture from Canvas Eelement

I was playing around with WebGL last night, doing some basic demos from the web. As an experienced OpenGL programmer, I was relieved to see how similar the WebGL API is (with some Javascript-specific tuning, of course).

I set about playing around with the excellent tutorials at http://learningwebgl.com. They step through some basic scenes up to some relatively advanced usage.

However, when playing around with the texture tutorial, it occurred to me that using an existing HTML element like a canvas tag as a texture would be a common use case for this technology. Unfortunately, WebGL is in its infancy and the amount of documentation availabel through a Google search is limited. After looking around for a while, it wasn’t obvious how I would accomplish this seemingly simple task.

After a bit of searching and some playing around with the code, I found (to my delight) that the texImage2D function on a WebGL context can be passed a canvas object for rendering. So, instead of passing it an image element like the tutorial shows, you can simply pass a canvas context:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);

where canvas2d is a canvas element that’s been grabbed from the DOM with something like document.getElementById(“canvas”). This should provide a nice way to create rich, 3D content that is generated from the 2D HTML 5 API.

UPDATE: It seems like, at least in the browser that I’ve been using for testing (Chromium 8.0 on Ubuntu), you can’t use NPOT (non-power of two) elements for the texture. This means that the element must have a width and height that is a power of two.