Saturday, December 29, 2012

UIView to UIImage

A simple way to capture a UIView in a UIImage or PDF.

Import CaptureView.h/.m

For an image screenshot:

UIImage* screenshotImage = [CaptureView viewToImage:self.view];
For a PDF screenshot:
NSData* pdfData = [CaptureView viewToPdf:self.view];

Primitive values with NSArray & NSDictionary


NSArray+Primitive

NSArray+Primitive extends NSArray and NSMutableArray to provide support for primitivesBOOL, char, int, float, CGPoint, CGSize, CGRect. The following example demonstrates int but all the other types work the same way.
NSMutableArray* array = [NSMutableArray array];
[array addInt:1]; // array = [1]
[array addInt:2]; // array = [1, 2]
int i = [array intAtIndex:0]; // i = 1
[array swapIndex1:0 index2:1]; // array = [2, 1]
[array replaceIntAtIndex:0 withInt:3];  // array = [3, 1]
[array insertInt:4 atIndex:1];
NSLog(@"%@", [array description]); // console shows [3, 4, 1]

NSDictionary+Primitive

NSDictionary+Primitive extends NSDictionary and NSMutableDictionary to provide support for primitivesBOOL, char, int, float, CGPoint, CGSize, CGRect. The following example demonstrates int but all the other types work the same way.
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
[dict setInt:1 forKey:@"int1"]; // dict = { int1:1 }
[dict setInt:2 forKey:@"int2"]; // dict = { int1:1, int2:2 }
int i = [dict intForKey:@"int1"]; // i = 1
NSLog(@"%@", [dict description]); // console shows { int1 = 1; int2 = 2; }

Sunday, June 17, 2012

UIFont properties

This is the most useful illustration I've found describing UIFont properties. Full article.

Tuesday, May 15, 2012

Hold For Developer Release

When creating a new version of an app there is an option to release the app after it's approved or hold it for the developer to release. I'm not aware of a way to modify this setting after the version has been created, so it's probably a good idea to always choose hold for developer release. Apps being submitted for the first time do not have this option and the work around appears to be to set the apps availability date to some time in the future in Rights And Pricing.

Update: Confirmed that setting availability date on a new app will hold it from the store release. The gotcha is the app position in iTunes "New" list appears to be based on approval date, so the longer you wait the less time your app shows in "New".

Monday, May 14, 2012

Browser Usage Stats

Global stats from W3C (browser, OS, screen resolution)

but the US has a heavier IE proportion:

US browser stats


Tuesday, April 17, 2012

SVN command line and @2x images

You can't escape it, adding and removing @2x images from the command line don't work. Thanks to a post by behaving on StackOverflow for the solution:


You need to add a "@" sign in the end to get SVN to process the file.
For example, if you had a file called foo@2x.png which you want to add to SVN, you would type:
svn add foo@2x.png@
If you have lots of files with the "@" symbol in their name that you want to process in a batch (i.e. use * wildcard), you can do something like this in OS X Terminal:
find . -name "*@*" | xargs -I % svn add %@
The above command will use the find utility to list out each file with @ in its filename and then pipe the path to the file to SVN using XARGS. XARGS will replace each occurrence of % with the path and append the special "@" at the end of the filename so that SVN will accept it.

Sunday, April 15, 2012

Blocks don't retain variables


I recently had user reports of The Rebus Show crashing in iOS 5.1. The app had been tested and even put through a beta program. The intermittent crash happened because the blocks don't retain variables, in this case myObj was intermittently released by iOS:

    runBlockAfterDelay(delay, ^{
        [myObj myMethod];
        myObj = nil;
    });

The fix was simple:

    __block MyObj* temp = myObj;
    runBlockAfterDelay(delay, ^{
        [temp myMethod];
        temp = nil;
    });

Tracking down this issue was difficult because it was intermittent, crash reports didn't symbolicate this code, ARC was responsible for the object's release, and because the crash manifested itself in an apparently unrelated event handler myMethod was responsible for removing. Fortunately, I noticed the event handler's owner address was different than the current object's address.