fix2x.sh – automatically create/resize @2x and non-@2x images for IOS

IOS Product Development, Unix
I've put together a quick bash script to automatically generate @2x and non-@2x images for IOS. The script looks through a directory, auto creates missing @2x or non-@2x files, and auto resizes the non-@2x files. Instructions: Download fix2x.sh from the Coder Cowboy Scripts GitHub Repo Copy the script to a directory Copy your original .png or .jpg files to the directory Open terminal & do something like the following: $ cd ~/Desktop/2x/ $ chmod +x fix2x.sh $ ./fix2x.sh . Script output will look something like this: Now processing file: ./normal name.png CREATING ./normal name@2x.png Original width: 15, height: 11 Small width: 7, height: 5 /Users/jason/Desktop/2x/normal name.png libpng warning: zero length keyword libpng warning: Empty language field in iTXt chunk /Users/jason/Desktop/2x/normal name.png Now processing file: ./twox name@2x.png Creating ./twox name.png Original…
Read More

TumbleOn Code

IOS Product Development
We've open sourced a variety of IOS Utilities and published them to our tumbleon-utils project over on bitbucket. All code is licensed with the Apache license, which like BSD or MIT, is a non-viral non-complicated license. Utilities included in tumbleon-utils: FileUtil - file IO and filename related utilities FrameUtils & UIView+FrameUtils - simplifies CGRect frame operations OperationManager - fixed capacity operation queue with weak or strong target pointers PrimitiveWrappers - simple classes wrapping a mutable primitive value TableViewHelper - simplifies UITableViewDelegate implementation TouchDelegatorView - UIView that delegates all touch events (and long press gestures) to a delegate UIWebView+Clean - simplifies UIWebView cleanup before deallocation WeakWrapper - simple wrapper class with a weak pointer to the inner object Thus far, we've released about half of the code we currently intend to…
Read More

IOS Autorotation Hell: Bad or wrong view position offsets after rotation

IOS Product Development
Edit: This is solved, answer at the end of this post. The Problem It looks like autorotation hell is back again. I'm trying to move some views around during a device rotation with strange results. I have created a simple hello world single view application. In this application I have two views: the view controller's view, and a square subview in the top left corner. The general idea here is that we want the main view to be full screen, and the little square view to always remain in the top left corner, but for some reason autorotation to landscape makes offsets go wonky for the main view. When the app rotates from portrait to landscape, the main view has an odd offset, but the subview is still in the…
Read More

IOS reminds me of IE

IOS Product Development, Midnight Ramblings, Tips, What I Just Learned
Developing for IOS is exactly like developing for IE. First, you knock the easy stuff out that *just works* simply without massive confusion. In browser land that means do your work in chrome or firefox first, whereas in IOS you basically do everything except auto-rotation first. Then, for the last step, you spend as much time handling IE bugs or IOS auto rotation hell as you spent developing up to that point. edit: The trick in IOS 6+ seems to be something like this inside your view controller.. - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { CGRect screenRect = [[UIScreen mainScreen] bounds]; screenRect = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height); //anchor to 0,0 if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) { //swap width & height screenRect = CGRectMake(0, 0, screenRect.size.height, screenRect.size.width); } self.view.frame = screenRect;…
Read More

Users aren’t stupid, your UI is.

IOS Product Development, Life and Philosophy, Midnight Ramblings
tl;dr; version: Get your head out of your ass, stop adding complex features that 90% of the world won't care for. Instead, learn to stop, breathe, and make your software products simple by focusing on usability consistently. Users aren't stupid, your UI is. In a big bad world of federated software product development, Usability is usually a bullet item way down at the bottom of a list of priorities for anyone but designers, at best. When your entire product team (including designers, developers, qa, etc) lives and breathes a particular software product for a period of months or years, *any* product becomes easy to understand. It's easy to understand because you're paid to think about, live, and breathe that product for 8 hours a day or better, for very long…
Read More

Making objective-c blocks synchronous

IOS Product Development, What I Just Learned
Many IOS libraries require you to do things asynchronously. Some of the better libraries provide both asynchronous and synchronous models to work with, but some do not. IOS' ALAssetLibrary is a good example of a library providing only asynchronous processing. The ALAssetLibrary allows you to fetch images, videos, and the like from a user's camera roll, and you're required to work with things in blocks, using a forced asynchronous method. In most cases, you'll want asynchronous processing when working with the ALAssetLibrary, but sometimes that may be overkill. If you want to synchronously reason about a series of assets in the library, you'll want to wrap the async block mess in something synchronous. For example, in my case, I wanted to synchronously check if asset URLS previously stored are still…
Read More

App store rejection for immediate crash

IOS Product Development
One of the apps I work on, TumbleOn, had a new version of the app rejected during review because it "crashed immediately". The troublesome part with the rejection was, we couldn't reproduce it. Every device we could find and hook up to xcode would run the app beautifully. If you're experiencing a similar problem, the problem doesn't show up when your app is being installed from the run menu of xcode. The crash only occurs when the archived .ipa file is dropped on to the device via xcode's organizer. In our case the fix to this problem was to update from xcode 4.3.x to 4.4. We found some threads on stack overflow saying this may be related to arc migration (something we had done), specifically something about armv6 and armv7…
Read More

FrameUtils – Objective-C Frame Utilities

IOS Product Development
Objective-C software developers often find themselves manipulating IOS or OSX UIView frames in various ways. Frames are resized, moved, centered, and endlessly debug printed. My buddy, Adam, and I became really annoyed at writing code like this over and over and over and .. //move the frame left by 5 pixels view.frame = CGRectMake(view.frame.origin.x - 5, view.frame.origin.y, view.frame.size.width, view.frame.size.height); In the example given, it's highly annoying to have a long line of code that says "view.frame.x.y.z" four different times when all we're trying to say is "just change the frame's position by 5 pixels". Unfortunately, a CGRect's inner properties are not modifiable, so developers are often resigned to code like that shown above. Fortunately, Adam and I decided to do something about the insanity of code verbosity for simple frame…
Read More

WIJL: IOS Memory Management Part 2

IOS Product Development, What I Just Learned
A few months ago, I posted an entry about some lessons learned in IOS Memory Management. In that entry (WIJL: IOS Memory Management), I covered a bunch of little objective-c memory management gotchas that helped us squash a few major memory leak bugs in TumbleOn. In the past few months, we've done some more work on TumbleOn, and we've learned a few more tricks of the trade, including some not-so-obvious problems, and some obvious bits that are worthwhile additions to any memory-leak-hunter's checklist. First, the not so obvious bits: Not So Obvious Memory Problem #1: UIWebView Antics It appears UIWebView is a bit quirky when it comes to memory management. Some theories maintain that the UIWebView will release properly if you load empty content into the UIWebView before deallocation, while…
Read More

WIJL: IOS Memory Management

IOS Product Development, What I Just Learned
My buddy Adam and I just emerged from a 3 evening/late-night binge of what I can only describe as hell. We were trying to fix memory problems with TumbleOn. We learned a bit on the way, and the most painful part of it all was that learning each bullet point below took more than average amounts of searching and reading and re-reading Apple docs. #1 - Double check that you use "self." in assignments When you seem to be having dealloc release problems, particularly with a bizarre error of [CALayer release] sent to deallocated instance, your problem may be that you set a property without using self., as in, you did this: myprop = [[[thing alloc] init] autorelease] When you should have done this: //note the "self." here.. self.myprop =…
Read More