BuySellAds.com

My book Barcodes with iOS 7 is nearing completion. Buy it now to get early access!
Our DNA is written in Objective-C
Jump

Directories: Temp, Cache, Documents

The first thing to learn when starting to persist data onto the iPhones solid state drive is that all apps have their own sandbox. Contrary to other operating systems where you have a shared documents folder, you have several directories for each individual apps. Now on the iPhone these sandbox directories all get a GUID in their name, so you have no way to hardcode or guess the real path they will end up on.

Luckily there is a method of getting the path for those directory, which I wrote about about a year ago: Getting Standard Paths. Today I will elaborate a bit on what I learned since then, it turns out that this is only half the story and as intermediate programmer you will want to use the correct kind of folder for each task.

Read more

Dr. Touch #014 – "Bonjour"

The iPhone and Apple News have never been as sexy … Jean Francois Martin sits in for speechless Oliver and provides a French twist.

This episode is brought to you by:

Dr. Touch’s Parts Store – easy to use yet professionally looking components that you can use to spruce up your own apps. Augmented Reality, Calendar Control, Pin Lock or Purchase Button are only some examples. You get full source code, no static library crap, and lifetime support by Dr. Touch himself. Check it out today!

Play

The Show Notes (aka Script) below the break…

Read more

Not for the Money

I learned a lesson today regarding happiness and programming. If you are concentrating on a single device and/or a niche of applications then often you feel like you’re the only one you loves the outcome of your never ending pecking at keys. And if you DO get feedback for your apps then often it’s only a rant in the reviews.

I already told you the story how SpeakerClock came to be. I did not write if for the money because frankly I did not think that anybody but myself would be using it. That’s also the reason why I am offering it for FREE initially. I’d rather get a couple of people to use it and send my feedback than have it sit on a virtual shelf collecting dust. Version 1.1 will be the one where I start charging, I decided. Or maybe the basic features now present will stay free, but some upgrades could be a good InAppPurchase.

I’m going to have a look at what we can learn about making great apps from an unexpected reaction I received.

Read more

iPhone Landscape Stands – Cheap or DIY

After having released SpeakerClock, a speech countdown clock, I got a couple of suggestions, one was not about the app itself, but about how you could stand the iphone on it’s side.

Kevin Jamison: “Now we just need to come up with a simple little stand similar to the iPod Touch uses to hold it in a tilted landscape mode. Maybe rubber coated feet so it won’t slide if you are using a podium.”

I remembered that every once in a while the blogosphere brought to light yet another clever way of solving such problems. A quick search on Google and YouTube yielded a couple of great solutions. Some that you can purchase , same that you can make yourself at little to no cost.

First let’s look at the professional solutions which typically cost between $5 and $10. After we’ve set the benchmark we’ll explore how we can achieve landscape stability ourselves. Building something useful out of physical things might be a welcome distraction from hours of coding Cocoa. :-)

Read more

SpeakerClock 1.0

I like to watch the TED Talks, it’s always something novel and instructive and makes me believe that the world is generally moving towards a brighter future led by a handful of rather bright fellows.

Now one thing these guys do extremely well is to give a TALK. Through experimentation it was found that at that length the speaker is forced to condense his message and be as clear as possible to get his point across. This constraint is enforced by the famous TED speaker LED clock. (It’s actually a countdown and not a clock, but people seem to prefer using the word “clock” over “countdown”)

This is a countdown at the edge of the stage which at a glance shows you what your remaining speaking time is. Also there is a traffic light of sorts. Shortly before the end of the time a green light switches to yellow to signal that you have to start wrapping up your message. Red means that it’s time for the closing remarks.

Obviously there are dedicated devices out there which aim to fill exactly the same need of visualizing a speakers time constraint. And of course there are a couple of iPhone apps providing this functionality. My second choice of the name of my app was taken by Talk Timer. Yet another is Speech Timer Free which provides the traffic light and the Premium version of it even allows for exporting of your speaking log.

I might continue to wish I were a great and inspirational speaker, but in the meantime one thing that I CAN do is make such a countdown clock for iPhone. I just had to do it, because the thought of the clock kept popping up in my head and kept distracting me from other projects.

My goal for SpeakerClock was this:

  • emulate the famous TED clock as closely as possible
  • use big red LED numbers (for which I had invented DTLEDNumberView)
  • allow for all customization and setting via touch gestures, all on the main screen
  • use the second page solely to showcase DTAboutViewController

Version 1 uses the maximum size possible of the digits that is available in landscape mode. Because of this you can see the digits from several meters away which is necessary if you want to position it so that you can move freely while giving your speech. To maximize the size of the clock I had to move minutes and seconds closer together and wrap the traffic lights underneath.

I made it a special point to finish the app within a single day and so I left out several things which I can put it if there is any interest in this app at all. The art of 1.0 is to concentrate on the required core features and leave some of your brilliant ideas for future versions. Here are some ideas still on my mental drawing board:

  • German localization (and other major languages) – language is not critical to understand usage of the clock all texts are on the instructions and about pages
  • Multiple Presets – might be an idea for a freemium upgrade
  • Recording of speaking logs, summing up your total speaking time, exporting, sharing …

I made a YouTube video to demonstrate the app:

I sent the app to Apple yesterday. SpeakerClock will be available on the app store initially for free to get user feedback.

UPDATE: 2 days after submission SpeakerClock is now available on the app store.

Things I learned implementing my first InAppPurchase

Yesterday I sent my first app off to Apple containing an InAppPurchase (IAP). It’s a free app that gives the user an option to pay a dollar for a premium features. That’s what they call Freemium these days. Free to try, premium to get some more.

The possibility for Freemium was only introduced in October 2009 when Apple finally gave in to developer’s wish to be able to do away with those dreaded Lite versions which have a very low conversion rate (about 1%) anyway. Until that time IAPs where only available for paid apps.

After developing on the premium content for about two weeks I hit my first roadblock. You apparently cannot configure an app id for use in a provisioning profile it it is already configured on another developer’s account.

If you are looking for a full walkthrough, this is not the article to provide that. Troy Brant has the most complete IAP Walkthrough on his blog. Instead this is a summary of my mental notes.

Read more

Dr. Touch #013 – "Long Stretch"

It’s just a couple more weeks until the first iPads hit the store. Still there are a couple of interesting news items that we shall explore. In this episode my guest is Barbara Gavin who organizes the Voices that Matter iPhone Developer’s Conference.

This episode is brought to you by:

Dr. Touch’s Parts Store – easy to use yet professionally looking components that you can use to spruce up your own apps. Augmented Reality, Calendar Control, Pin Lock or Purchase Button are only some examples. You get full source code, no static library crap, and lifetime support by Dr. Touch himself. Check it out today!

Play

My Show Notes (aka Script) below the break…

Read more

Uploading UIImages to TwitPic

One day of the week I hope to do something that’s not really business oriented, I call it my “Friday-Project”. This title comes from my time in IT where you would generally avoid do any major changes to the systems you are maintaining on Fridays because nobody likes to work on fixing these on the following weekend. So Friday is a great day to just experiment, prototype or dream. At Google they are supposedly giving their employees 20% of their working time for such projects, so I am dedicating as much time to playful exploration as well.

Today I want to explore and hopefully finish some code to upload an image to TwitPic. So the first step is to have a look at their API documentation which is not very pretty, but at least it’s complete. There we see that we want to implement the uploadAndPost function.

METHOD: http://twitpic.com/api/uploadAndPost

Use this method to upload an image to TwitPic and to send it as a status update to Twitter.

Fields to post in post data should be formatted as multipart/form-data:

- media (required) – Binary image data
- username (required) – Twitter username
- password (required) – Twitter password
- message (optional) – Message to post to twitter. The URL of the image is automatically added.

Sample response:

<?xml version=”1.0″ encoding=”UTF-8″?>
<rsp status=”ok”>
<statusid>1111</statusid>
<userid>11111</userid>
<mediaid>abc123</mediaid>
<mediaurl>http://twitpic.com/abc123</mediaurl>
</rsp>

For this we need to construct an HTTP POST request to the URL http://twitpic.com/api/uploadAndPost and construct a multipart body with binary image data, Twitter username, password and an optional message. The response will be XML giving us the URL we can use to link to the picture.

Having the parameters intermixed makes it a bit harder especially if you have never constructed a multipart body before. The easiest method of image uploading is if you can specify parameters in the URL, but the designer of this API thought it smarter to have it in the body. But don’t worry, we’ll get this figured out as well.

Read more

App Information String Tokens

For my current project DTAboutViewController I need to be able to specify tokens in my strings that would be replaced by information about the app at runtime. Of specific interest are CFBundleDisplayName and CFBundleVersion which are both in info.plist. Usually you could hard-code these into your app strings or maybe do a global #define, but for my component I wanted to have the most flexibility with the least amount of work in subsequent project that would use that.

So I put together a category extension for NSString which also shows off how to use NSScanner to find tokens and replace them with values from your info dictionary.

NSString+Helpers.h

#import 
 
@interface NSString (Helpers)
 
- (NSString *) stringBySubstitutingInfoTokens;
 
@end

NSString+Helpers.m

#import "NSString+Helpers.h"
 
@implementation NSString (Helpers)
 
- (NSString *) stringBySubstitutingInfoTokens
{
	NSMutableString *tmpString = [NSMutableString stringWithString:self];
	NSScanner *scanner = [NSScanner scannerWithString:self];
 
	NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
 
 
	while (![scanner isAtEnd])
	{
		if ([scanner scanString:@"$" intoString:nil])
		{
			NSString *tokenName;
 
			if ([scanner scanCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:&amp;tokenName])
			{
				id value = [infoDict objectForKey:tokenName];
 
				if (value &amp;&amp; [value isKindOfClass:[NSString class]])
				{
					[tmpString replaceOccurrencesOfString:[@"$" stringByAppendingString:tokenName] withString:value options:NSLiteralSearch range:NSMakeRange(0, [tmpString length])];
				}
			}
		}
 
		[scanner scanUpToString:@"$" intoString:nil];
	}
 
	return [NSString stringWithString:tmpString];
}
@end

The code works by skipping all characters until it encounters a $, which will be our token identifier. From this position the name of the token is until the first non-alphanumberic character, like a space or period. Then it tries to get a value from the bundle’s info dictionary. If it succeeds the token is replaced in a temporary string, if not it is left unchanged.

Note how I am passing nil into scan functions if I am only interested in skipping characters. If I am interested in the scanned result, then I am passing the address of a pointer to an NSString, that’s the reason for the &tokenName. The scan method creates an autoreleased copy of the scanned string and puts the pointer to this string into the parameter the address of which you have passed. That’s unusual in objective-C and seen more often in pure C code, so be aware of that.

Now with this code I gain a very useful way of displaying copyright information as the section footer of my settings table.

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
	return [@"© 2010 Drobnik.com. $CFBundleDisplayName $CFBundleVersion" stringBySubstitutingInfoTokens];
}

This will look like this, the app’s bundle display name is “About” and the version string is “1.0″.

With this method it’s even thinkable to put your own information into info.plist. Like for example the ID of your app which you would use for a direct link to the review page. Some people complain that Cocoa does not have regular expression support, but actually if you know how to use NSScanner properly you can do even more with it than trying to piece together working regexps.

“Are You a Cocoa Crack?” Quiz (2)

It’s been more than half a year since I published the first installment of this Quiz aimed at Cocoa Cracks. Back then people seemed to like the challenges I presented. So I collected a few more nuggets. If you ever stumbled on an crash or strange result that you did not expect, then mail it to me.

These questions will show if you are really the Cocoa Crack you like to believe to be. To see the answer highlight the answer text with your mouse. No peeking! Respond in the comments how many you got correct.

Quiz: Warm Up. Your UI designer gave you a PNG with the instruction “just tile this in the background” of a UIView. Do you have to subclass UIView, overriding the drawRect of the view and performing drawImage for all tiles? Or is there a simpler method?

Answer: You create a UIImage by loading the PNG and then create a “color” from it with [UIColor colorWithPatternImage:image]. Then you apply this as the background color of the view.


Quiz: Suddenly your app crashes and when the debugger opens it first loads lots of stack frames. All you did is override a property like shown below. What’s the bug? Bonus Question: where’s the memory leak?

- (void) setTextColor:(UIColor *)newTextColor
{
	if (newTextColor != textColor)
	{
		[textColor release];
 
		if (newTextColor)
		{
			self.textColor = [newTextColor retain];
		}
		else // default
		{
			self.textColor = [[UIColor whiteColor] retain];
		}
		bubbleView.highlightedTextColor = textColor;
	}
}

Answer: You have an endless recursion. self.textColor is a simplified way to write [self setTextColor:]. So this method keeps calling itself until the stack is full and your app gets terminated. The leak is calling retain on an assignment to a retaining property. But if you fix the crashing bug by removing both self then there is no leak.


Quiz: You want to draw two lines in a drawRect, a horizontal black line and a white line 1 pixel below it. So you write the following code. But instead of the intended result you get this picture in magnification, the black is dark gray and the white is a lighter shade of gray. Why is that and how would you fix it?

CGContextRef currentContext = UIGraphicsGetCurrentContext();
 
// Draw a black line at the top and a white line 1 pixel below
 
CGContextSetLineWidth(currentContext, 1);
 
CGContextSetRGBStrokeColor(currentContext, 0.0, 0.0, 0.0, 1.0); // Black
CGContextMoveToPoint(currentContext, 0, 0); // top left
CGContextAddLineToPoint(currentContext, rect.size.width, 0); // to top right
CGContextStrokePath(currentContext);
 
CGContextSetRGBStrokeColor(currentContext, 1.0, 1.0, 1.0, 1.0); // White
CGContextMoveToPoint(currentContext, 0, 1); // left
CGContextAddLineToPoint(currentContext, rect.size.width, 1);
CGContextStrokePath(currentContext);

Answer: Core Graphics does not work on pixels directly, that’s why you use floating point numbers for coordinates. It works on coordinates and the resulting bitmap is always rendered. Half of the line width is always applied half a unit to each side of the line. To remedy this you need to move the coordinates of the lines by half a unit up or down.

(Thanks to Michael Kaye for sending this in)


Quiz: You have a UITableView and would like for it to have rounded corners. What’s the fastest way to achieve that? Which header is necessary?

Answer: You can have any UIView have rounded corners by setting the cornerRadius property of it’s CALayer. The layer of a UIView is actually what’s responsible for drawing the contents of the view. You need: to import <QuartzCore/QuartzCore.h>


Quiz: You have created a UIViewController which shows a UIWebView and has a navigation bar. You want to set the title on the bar to be the same as the title of the HTML document once loading has finished. Would you need to parse the HTML with NSScanner to find the <title> tag and extract it? Or is there a simpler method?

Answer: In the webViewDidFinishLoad: delegate method you retrieve the title via javascript and set it like that. self.title = [webView stringByEvaluatingJavaScriptFromString: @"document.title"];


Quiz: You have written code to load some UIImages in the background (performSelectorOnBackgroundThread or NSInvocationOperation). The loading code calls the method below to resize the loaded image. This has “always working before”, but suddenly you keep getting a EXC_BAD_ACESS on the line marked. You have double checked all retains and even set NSZombieEnabled to YES because usually you get this message if you are using an overreleased object. But that did not fix the problem. What’s the reason for the crash and how would you fix it?

+ (UIImage*)imageWithImage:(UIImage*)image
			  scaledToSize:(CGSize)newSize;
{
	UIGraphicsBeginImageContext( newSize );
	[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];   // &lt;- crash
	UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
 
	return newImage;
}

Answer: UIKit is not thread-safe. Therefore all drawing via UIKit needs to happen on the main thread. The UIGraphicsBeginImageContext works to create the context, but the memory for it is owned to the main thread and trying to access it with drawInRect from another thread is causing this exception. To fix it you need to rewrite this method to create your own bitmap context on the non-main thread so that you then own the memory for it. After creating the bitmap context you draw the image to it with CGContextDrawImage and then create a new CGImage with CGBitmapContextCreateImage. From the CGImage you create a UIImage to return from the method.


Quiz: Off the top of your head: how many methods do you know of having a piece of code contained in one method being performed in the background? Which?

Answer: Correct Answers are: performSelectorOnBackgroundThread and creating an NSInvocationOperation from the selector as those work on an existing method. Creating an NSOperation sub-class or manual threading with NSThread are also valid answers, but those require that you move the code into a new class or need to be well versed with threading voodoo.


So how many answers did you know? Be honest! If you also have a Cocoa riddle like these to contribute please mail them directly to me (oliver@drobnik.com) and I will publish them in this format.