Icon Sizes and Guidelines for iOS and Android

by Andy Selvig 25. February 2012 17:46

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)
Color Key:
Android Only
iOS Only
Android and iOS

Tags:

Android | Icons | iOS

Get Ready for App Submission

by Bekki Freeman 23. January 2012 14:33

Here's a quick list of the information to give to your developer so that they can submit your app.

 

  1. App Name -- This is the name that appears for the app in the App Store.
  2. 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
  3. App Icon -- a 512px x 512px icon that displays in the app store.  This can be the same image used as the app icon on the actual device
  4. 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.
  5. Keywords -- These are the terms that help people find your app in the App Store.  The limit is 150 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.
  6. Category and Secondary Category -- Determine which categories your app falls into.  The secondary category is optional.
  7. Price -- How much do you want to sell your app for?
  8. 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.

 

Tags: , ,

iOS | iPhone

Inline Attachments Using MFMailComposeViewController

by Bekki Freeman 29. December 2011 05:28

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:

- (void)composeEmail:(UIWebView *)webView

{

    MFMailComposeViewController *email = [[MFMailComposeViewController alloc] init];

    [email setToRecipients:[NSArray arrayWithObject:@"someone@somewhere.com"]];

    [email setSubject:@”Your Subject"];

    NSString *body = @"<html><head></head><body>Your message.</body></html>";

    [email setMessageBody:body isHTML:YES];

    [email setMailComposeDelegate:self];

   

    // Create image

    UIGraphicsBeginImageContext(webView.frame.size);

    [webView.layer renderInContext:UIGraphicsGetCurrentContext()];   

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

 

    // Attach image   

    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString *path = [docs stringByAppendingPathComponent:@"markup.jpg"];

    [UIImageJPEGRepresentation(image, 0.25) writeToFile:path atomically:YES];

    NSData *data = [NSData dataWithContentsOfFile:path];

    [email addAttachmentData:data

                    mimeType:@"image/jpeg"

                    fileName:@"markup.jpg"];   

   

    [self presentModalViewController:email animated:YES];   

    [email release];   

} 

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.

Tags: , , ,

iOS | iPhone | MS Outlook

Top Reasons To Avoid Blackberry Development

by Bekki Freeman 4. November 2011 15:47

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 | Mobile Development

iOS5 Upgrade Nightmares

by Bekki Freeman 27. October 2011 04:10

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 | iPhone

Easily create a new text file in Finder on OS X

by Andy Selvig 25. October 2011 09:55

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 App

by Bekki Freeman 3. October 2011 05:00

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 google your apps:

 

-(void)viewAllApps {

    NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.com/apps/developername"];

    [[UIApplication sharedApplication] openURL:url];

}


Theme Google Chrome

Gazoomy Google Wallpaper

Tags: , ,

iPhone

Rendering to a PDF on iOS using UIKit

by Andy Selvig 28. September 2011 09:38

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: , , ,

iPhone | Mobile Development

Custom view class in MonoTouch

by Andy Selvig 8. April 2011 21:53

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 <ClassName> 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

TinyButtonator - Yet Another Button Generator!

by Andy Selvig 5. April 2011 21:12

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!

 

Tags: , , ,

Android | iPhone | Web Applications | TinyButtonator

Page List