<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ObjColumnist</title>
	<atom:link href="http://objcolumnist.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://objcolumnist.com</link>
	<description>Coding under the Hammer</description>
	<lastBuildDate>Sun, 10 Jan 2010 14:28:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Show hidden files in the Finder</title>
		<link>http://objcolumnist.com/2010/01/10/show-hidden-files-in-the-finder/</link>
		<comments>http://objcolumnist.com/2010/01/10/show-hidden-files-in-the-finder/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 14:28:00 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Quick Tip]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=164</guid>
		<description><![CDATA[Sometimes when you are digging around in the under pinnings of Mac OS X, you need to access folders and files that are normally hidden by the OS. Thankfully there is preference in the Finder for this, which you can turn on and off in the Terminal.
The command is:

defaults write com.apple.Finder AppleShowAllFiles YES

The Finder needs [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes when you are digging around in the under pinnings of Mac OS X, you need to access folders and files that are normally hidden by the OS. Thankfully there is preference in the Finder for this, which you can turn on and off in the Terminal.</p>
<p>The command is:<br />
<code><br />
defaults write com.apple.Finder AppleShowAllFiles YES<br />
</code></p>
<p>The Finder needs to be restarted for this change to take effect. Luckily there is a Terminal command for this too:</p>
<p><code><br />
killall Finder<br />
</code></p>
<p>Once you are done playing around with hidden files, you can stop showing them by replacing YES with NO in the original terminal command.</p>
<p><code><br />
defaults write com.apple.Finder AppleShowAllFiles NO<br />
</code></p>
<p>It is as simple as that, but make sure your don&#8217;t break anything.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2010/01/10/show-hidden-files-in-the-finder/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Redirecting NSLog to a log file</title>
		<link>http://objcolumnist.com/2009/12/19/redirecting-nslog-to-a-log-file/</link>
		<comments>http://objcolumnist.com/2009/12/19/redirecting-nslog-to-a-log-file/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 20:08:18 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=153</guid>
		<description><![CDATA[Using NSLog is all well and good for debugging iPhone OS applications when the device is connected to your Mac, but what about when it is not. Often you want to give builds of your application to people that don&#8217;t have Xcode installed (or can&#8217;t get the silly certificates to work !!!), or just as [...]]]></description>
			<content:encoded><![CDATA[<p>Using NSLog is all well and good for debugging iPhone OS applications when the device is connected to your Mac, but what about when it is not. Often you want to give builds of your application to people that don&#8217;t have Xcode installed (or can&#8217;t get the silly certificates to work !!!), or just as commonly, to test if the application works outside of your lovely office which has a perfect WiFi connection.</p>
<p>When I first thought about this problem, I was thinking along the lines of build a custom log function lets say MagicLog() and this calls a function that saves the string to a file. The problem with this is that I would have to go through all of my code and add MagicLog() to everywhere that I have NSLog(), that seemed a bit to verbose for my liking.</p>
<p>After searching on the internet I found out that (rather obvious) NSLog runs over standard error. This means that you are able to simply redirect standard error to a file using the ANSI function freopen().</p>
<p><code><br />
FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict stream);<br />
</code></p>
<p>http://www.opengroup.org/onlinepubs/000095399/functions/freopen.html</p>
<p>Before we can save NSLog() to a file, we first have to find a place to save it. The best place to do this is the application&#8217;s documents folder. To get this you can use the following code snippet:</p>
<p><code><br />
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);<br />
NSString *documentsDirectory = [paths objectAtIndex:0];<br />
</code></p>
<p>Once we have the documents folder, we need to give a name to the file. To make it easy for me I just name it &#8220;the date&#8221;.log :</p>
<p><code><br />
NSString *fileName =[NSString stringWithFormat:@"%@.log",[NSDate date]];<br />
</code></p>
<p>To make this into a valid path, use the NSString method stringByAppendingPathComponent</p>
<p><code><br />
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];<br />
</code><br />
The last step is to redirect stderr to this file</p>
<p><code><br />
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);<br />
</code></p>
<p>To keep my code maintainable I keep all of this as a function, and I call it in my AppDelegate if I want to turn this functionality on.</p>
<p><code><br />
- (void)redirectNSLogToDocumentFolder{<br />
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);</p>
<p>	NSString *documentsDirectory = [paths objectAtIndex:0];</p>
<p>	NSString *fileName =[NSString stringWithFormat:@"%@.log",[NSDate date]];</p>
<p>	NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];</p>
<p>	freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);<br />
}</p>
<p></code><br />
<strong>Getting the file.</strong></p>
<p>Now that you have logged all the information you need, you will want to get this off of the device. Thankfully this is easy as well. Simply open the organiser in Xcode and select the device that is currently connected to your Mac.</p>
<p>A the bottom of the main pain there is an application section. Open the detail disclosure on the application you want to get the data from, and hit the little download button to the right of the Application Data package. You will be prompted to save this folder to your mac.</p>
<p><strong>Warning:</strong><br />
Writing to the file system on the iPhone is slow, so this will effect the performance of your application. Therefore DO NOT ship an application with this in, or give it to people that can&#8217;t stand poor performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/12/19/redirecting-nslog-to-a-log-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>URL Encoding</title>
		<link>http://objcolumnist.com/2009/10/25/escaping-a-url/</link>
		<comments>http://objcolumnist.com/2009/10/25/escaping-a-url/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 14:27:49 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=137</guid>
		<description><![CDATA[If you have tried to send any information using a GET web request, you would have come across an annoying problem. That annoying problem is making sure that the URL is correctly encoded.
At first glance it would seem that the Cocoa Frameworks do this for you, and you would be right &#8230;. well kind of.
The [...]]]></description>
			<content:encoded><![CDATA[<p>If you have tried to send any information using a GET web request, you would have come across an annoying problem. That annoying problem is making sure that the URL is correctly encoded.</p>
<p>At first glance it would seem that the Cocoa Frameworks do this for you, and you would be right &#8230;. well kind of.</p>
<p>The issue is that by default most of these methods leave characters such as &#038; = ? within a URL, as they are strictly speaking valid. The problem is that these characters have special meanings in a GET request, and will more than likely make your request in valid.</p>
<p>Luckily there is a function in Core Foundation that helps:<br />
<code><br />
CFStringRef CFURLCreateStringByAddingPercentEscapes (<br />
   CFAllocatorRef allocator,<br />
   CFStringRef originalString,<br />
   CFStringRef charactersToLeaveUnescaped,<br />
   CFStringRef legalURLCharactersToBeEscaped,<br />
   CFStringEncoding encoding<br />
);<br />
</code></p>
<p>What makes this function useful, is the <strong>legalURLCharactersToBeEscaped</strong> parameter. This will escape legal characters such as &#038; ? = if they are supplied. This allows you to escape parameters using the following code.<br />
<code></p>
<p>CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)parameter, NULL, CFSTR(":/?#[]@!$&#038;’()*+,;="), kCFStringEncodingUTF8)<br />
</code></p>
<p>An example of when to use this, is Twitters Update status API. You can find that here http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses%C2%A0update</p>
<p>To update your status to the following:</p>
<p><strong>This is my status</strong></p>
<p>You would need to post up the following URL:</p>
<p>http://twitter.com/statuses/update.xml?status=This%20is%20my%20status</p>
<p>As this is such a common problem of mine, I have created a category on NSURL. This allows you to pass in a base URL and a parameters dictionary.</p>
<p><code></p>
<p>+ (NSURL *)URLWithBaseString:(NSString *)baseString parameters:(NSDictionary *)parameters{</p>
<p>	NSMutableString *urlString =[NSMutableString string];</p>
<p>	//The URL starts with the base string<br />
	[urlString appendString:baseString];</p>
<p>	NSInteger keyIndex = 0;</p>
<p>	for (id key in parameters) {</p>
<p>//First Parameter needs to be prefixed with a ? and any other parameter needs to be prefixed with an &#038;<br />
		if(keyIndex ==0)<br />
		{<br />
			[urlString appendFormat:@"?%@=%@",key,CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[parameters valueForKey:key], NULL, CFSTR(":/?#[]@!$&#038;’()*+,;="), kCFStringEncodingUTF8)];<br />
		}else{<br />
			[urlString appendFormat:@"&#038;%@=%@",key,CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[parameters valueForKey:key], NULL, CFSTR(":/?#[]@!$&#038;’()*+,;="), kCFStringEncodingUTF8)];<br />
		}</p>
<p>		keyIndex++;<br />
	}</p>
<p>	return [NSURL URLWithString:urlString];</p>
<p>}</code></p>
<p>Using a parameters dictionary keeps the code nice and clean, but beware, to use the category method above you still have to make sure that your keys, and the base URL are correctly encoded (no spaces or invalid characters !!!!!).</p>
<p>As we now have a category method to do all the hard work for us, to create the Twitter URL you just need to do the following:<br />
<code><br />
        NSString *baseString=@"http://twitter.com/statuses/update.xml";<br />
	NSDictionary *dictionary=[NSDictionary dictionaryWithObjectsAndKeys:@"This is my status",@"status",nil];<br />
	NSURL *url=[NSURL URLWithBaseString:baseString parameters:dictionary];<br />
</code></p>
<p>And thats it. Obviously this category can be used for things other than twitter &#8230;.. if you really want to.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/10/25/escaping-a-url/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reopening an application&#8217;s main window by clicking on the Dock Icon</title>
		<link>http://objcolumnist.com/2009/08/09/reopening-an-applications-main-window-by-clicking-the-dock-icon/</link>
		<comments>http://objcolumnist.com/2009/08/09/reopening-an-applications-main-window-by-clicking-the-dock-icon/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 10:57:29 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Quick Tip]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=128</guid>
		<description><![CDATA[When building Mac applications, Apple usually takes care of most of the default behaviours for you. One thing that Mac applications don&#8217;t do by default is, reopening the applications main window (if it has been closed), when the dock icon is pressed.
Although this information is very hard to find in the documentation, but is actually [...]]]></description>
			<content:encoded><![CDATA[<p>When building Mac applications, Apple usually takes care of most of the default behaviours for you. One thing that Mac applications don&#8217;t do by default is, reopening the applications main window (if it has been closed), when the dock icon is pressed.</p>
<p>Although this information is very hard to find in the documentation, but is actually very easy to. The method you need to find is:</p>
<p><code><br />
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag;<br />
</code></p>
<p>This is an optional delegate method that your AppDelegate can choose to implement, and is called when the user presses your application&#8217;s dock icon. The bool flags indicates whether the application has any visible windows. To reopen your application&#8217;s main window, you need to have a pointer to it (In the example below assume that it is defined as NSWindow *window; in the header file). If you do have a pointer to then you simple need to implement the code below.<br />
<code></p>
<p>- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag{</p>
<p>	if(flag==NO){<br />
		[window makeKeyAndOrderFront:self];<br />
	}<br />
	return YES;<br />
}</code></p>
<p>It is as simple as that.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/08/09/reopening-an-applications-main-window-by-clicking-the-dock-icon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple UIView based Animations on the iPhone</title>
		<link>http://objcolumnist.com/2009/07/18/simple-uiview-based-animations-on-the-iphone/</link>
		<comments>http://objcolumnist.com/2009/07/18/simple-uiview-based-animations-on-the-iphone/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 11:33:39 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[CocoaTouch]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=108</guid>
		<description><![CDATA[Although for complex animation sequences on the iPhone you need to use either the OpenGL or Apple&#8217;s very own Core Animation Framework, a lot of simple animations can be achieved with the methods found in the UIView class. All these animations are actually built upon Core Animation, but they have been wrapped up for you [...]]]></description>
			<content:encoded><![CDATA[<p>Although for complex animation sequences on the iPhone you need to use either the OpenGL or Apple&#8217;s very own Core Animation Framework, a lot of simple animations can be achieved with the methods found in the UIView class. All these animations are actually built upon Core Animation, but they have been wrapped up for you to use with very little code.</p>
<p>All animations triggered by the UIView class happen within a animation block.</p>
<p>To start an animation block you use the UIView Class method:<br />
<code><br />
+ (void)beginAnimations:(NSString *)animationID context:(void *)context;<br />
</code></p>
<p>The animation ID is used in delegate call backs for such things as the beginning and end of animation blocks. The context is  an additional piece of information that can be passed through.</p>
<p>As both of these parameters are optional, you comenly see:<br />
<code><br />
[UIView beginAnimations:@"" context:NULL];<br />
</code></p>
<p>To commit these animations, and therefore end the animation block, you need to use the UIView class method:<br />
<code><br />
+ (void)commitAnimations<br />
</code></p>
<p>So what types of animations can you do ? well quite a few.</p>
<p>You can animate views by:</p>
<ul>
<li>Changing their alpha</li>
<li>Changing there size</li>
<li>Changing there location</li>
</ul>
<p>In a single animation block you can animate multiple views, and you are also able to nest animation blocks.</p>
<p>So lets do a common example. When a UITableViewCell is being edited you often want to make a UILabel&#8217;s (label) alpha change to 0 so it is hidden:</p>
<p><code></p>
<p>[UIView beginAnimations:@"" context:NULL];<br />
[label setAlpha:(editing ? 0.0 : 1.0)];<br />
[UIView commitAnimations];</p>
<p></code></p>
<p>For those new to C programming:<br />
<code><br />
(editing ? 0.0 : 1.0)<br />
</code></p>
<p>Is equivlant to:<br />
<code></p>
<p>   if(editing)<br />
   {<br />
         0.0;<br />
   }else{<br />
         1.0;<br />
   }<br />
</code></p>
<p>So for the second example we also have a UILabel (label), that we want to grow when the animation code is run. We also want this animation to last 2 seconds, so the user can admire our work. In addition to this, we want the animation to &#8220;ease in&#8221;. This is known as the animation curve. The animation curves that are available are</p>
<ul>
<li>ease in (slow then fast)</li>
<li>ease out (fast then slow)</li>
<li>ease in and out (slow, fast, slow)</li>
<li>linear (constant speed)</li>
</ul>
<p>We would do this animation using the following animation block:</p>
<p><code></p>
<p>[UIView beginAnimations:@"" context:NULL];</p>
<p>//The new frame size<br />
[label setFrame: CGRectMake(0,0,320,100)];</p>
<p>//The animation duration<br />
[UIView setAnimationDuration:2.0];</p>
<p>[UIView setAnimationDelay: UIViewAnimationCurveEaseIn];</p>
<p>[UIView commitAnimations];</p>
<p></code></p>
<p>This is just a brief overview of the animations you can do using the UIView class, but it should be enough to get you started. The UIView methods also include delegate call backs for when an animation starts and end. For more information see Apple&#8217;s Documentation.</p>
<p>If the UIView class does not have what you need, you will probably need to use the Core Animation framework. While using this framework is not trivial, it is not as hard as using OpenGL (which is used commonly for 3D games), and you can build some fantastic animations using it.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/07/18/simple-uiview-based-animations-on-the-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changing the name of an iPhone application</title>
		<link>http://objcolumnist.com/2009/07/04/changing-the-name-of-an-iphone-application/</link>
		<comments>http://objcolumnist.com/2009/07/04/changing-the-name-of-an-iphone-application/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 11:26:10 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Quick Tip]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=105</guid>
		<description><![CDATA[When you finally come to release your application after months of hard work, your might want to change the name of the application that appears on the iPhone springboard, and if you use it, the settings application.
To change the name of an iPhone application is very easy. Simply open the Xcode project, and then scroll [...]]]></description>
			<content:encoded><![CDATA[<p>When you finally come to release your application after months of hard work, your might want to change the name of the application that appears on the iPhone springboard, and if you use it, the settings application.</p>
<p>To change the name of an iPhone application is very easy. Simply open the Xcode project, and then scroll down to the &#8220;Targets&#8221; section, which the the &#8220;Groups &#038; Files&#8221; part of Xcode. Select the application&#8217;s target and &#8220;Get info&#8221; on it using cmd-i or ctrl clicking it, and select &#8220;Get Info&#8221; from the menu.</p>
<p>In the build section of the get info window, you need to change the &#8220;Product Name&#8221; value to whatever you want your application to be called. When you change this value make sure that the configuration pop up menu (at the top of the window) is set to &#8220;All Configurations&#8221;, so it takes effect in all of your builds.</p>
<p>For the change of name to take effect, simply clean your targets and rebuild your application.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/07/04/changing-the-name-of-an-iphone-application/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NSUserDefaults (Preferences)</title>
		<link>http://objcolumnist.com/2009/06/28/nsuserdefaults-preferences/</link>
		<comments>http://objcolumnist.com/2009/06/28/nsuserdefaults-preferences/#comments</comments>
		<pubDate>Sun, 28 Jun 2009 11:57:44 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[CocoaTouch]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=89</guid>
		<description><![CDATA[Not everybody likes their applications to behave in the same way, and this is why the majority of Mac and iPhone applications have preferences. The default way to handle these preferences is using the class NSUserDefaults.
NSUserDefaults are stored on the file system as .plist, which is simply an XML document. The way you access NSUserDefaults [...]]]></description>
			<content:encoded><![CDATA[<p>Not everybody likes their applications to behave in the same way, and this is why the majority of Mac and iPhone applications have preferences. The default way to handle these preferences is using the class NSUserDefaults.</p>
<p>NSUserDefaults are stored on the file system as .plist, which is simply an XML document. The way you access NSUserDefaults programatically is very much like accessing an NSMutableDictionary, that is by using keys.</p>
<p><strong>Setting User Defaults</strong></p>
<p>NSUserDefaults can be a bool, float, integer or an object. So if you wanted to set the autosave option (which is a BOOL) for your application to be YES, you would write:<br />
<code><br />
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"AutoSave"];<br />
</code></p>
<p>Moreover if you wanted to set the person&#8217;s name to ObjColumnist you would write:<br />
<code></p>
<p>[[NSUserDefaults standardUserDefaults] setObject:@"ObjColumnist" forKey:@"PersonName"];<br />
</code></p>
<p><strong>Reading User Defaults</strong></p>
<p>Reading the user defaults is just as easy as setting them. If we wanted to retrieve the 2 values we stored above, you would simply write:<br />
<code></p>
<p>NSString *name = [ [NSUserDefaults standardUserDefaults] stringForKey:@"PersonName"];<br />
BOOL autoSave =  [ [NSUserDefaults standardUserDefaults] boolForKey:@"AutoSave"];<br />
</code></p>
<p>You should also notice that there is a convenience method for retrieving a string for a key, even though we set it as an object.</p>
<p>It is also important to be aware that if you attempt to retrieve a numeric value such as an integer, <em>integerForKey:</em> for a non existent key, you will get the value 0. This is obviously an issue if 0 would trigger a certain preference in you application.</p>
<p><strong>Setting the default user defaults</strong></p>
<p>So you can now set and read the user defaults, but how do you assign their default values ?</p>
<p>The answer is <strong>registerDefaults:</strong></p>
<p>This method is usually called in the initialize (class) method of a given application&#8217;s AppController. The parameter for this method is an NSDictionary. The code below sets the default preference for the AutoSave option to YES, and the person&#8217;s name to @&#8221;unknown&#8221;.<br />
<code></p>
<p>NSMutableDictionary *defaults=[NSMutableDictionary dictionary];</p>
<p>[defaults setObject:[NSNumber numberWithBool:YES] forKey:@"AutoSave"];<br />
[defaults setObject:@"unknown" forKey:@"PersonName"];</p>
<p>[[NSUserDefaults standardUserDefaults] registerDefaults: defaults];</p>
<p></code></p>
<p>One thing that Cocoa does for you automatically without needing any extra code, is that it only saves to the .plist the values that are different to the defaults values, that were registered using <strong>registerDefaults:</strong> . This means that if the user does not change any of their default preference settings, there will no be a preference file created.</p>
<p><em>Note: The code above just stores the preference for the AutoSave option, you still have to create the code to manage the saving of data yourself.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/06/28/nsuserdefaults-preferences/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Helper Objects (Delegate and DataSource)</title>
		<link>http://objcolumnist.com/2009/06/14/helper-objects-delegate-and-datasource/</link>
		<comments>http://objcolumnist.com/2009/06/14/helper-objects-delegate-and-datasource/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 14:19:20 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[CocoaTouch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=69</guid>
		<description><![CDATA[Helper Objects are used throughout Cocoa and CocoaTouch, and usually take the form of a delegate or dataSource. They are commonly used to add functionality to an existing class without having to subclass it.
In software engineering, the delegation pattern is a technique where an object outwardly expresses certain behaviour but in reality delegates responsibility for [...]]]></description>
			<content:encoded><![CDATA[<p>Helper Objects are used throughout Cocoa and CocoaTouch, and usually take the form of a <em>delegate</em> or <em>dataSource</em>. They are commonly used to add functionality to an existing class without having to subclass it.</p>
<blockquote><p>In software engineering, the delegation pattern is a technique where an object outwardly expresses certain behaviour but in reality delegates responsibility for implementing that behavior to an associated object in an Inversion of Responsibility. The delegation pattern is the fundamental abstraction that underpins composition (also referred to as aggregation), mixins and aspects.</p>
<p>http://en.wikipedia.org/wiki/Delegation_pattern</p>
</blockquote>
<p>The most common use of helper objects in iPhone development is when using UITableViews. When you instantiate a UITableViewController this class is automatically assigned to be the delegate and dataSource of the table view it holds.</p>
<p><code><br />
self.tableView.delegate=self;<br />
self.tableView.dataSource=self;<br />
</code></p>
<p>The UITableView then calls the appropriate delegate method when it needs information, such as:</p>
<p><code><br />
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath<br />
</code></p>
<p>This ask the delegate, what is the height for the row at a given index path, so in your UITableViewController (the delegate) you would write the following, if you wanted the row to be 44 pixels high (the default).</p>
<p><code><br />
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{</p>
<p>      return 44;<br />
}<br />
</code></p>
<p><strong>Writing your own delegate.</strong></p>
<p>Most delegates are declared as a protocol, so the compiler knows that the delegate implements the required methods.</p>
<p><strong>Example:</strong></p>
<p>You have created a subclass of UITextView (e.g. OBCTextView), that you use in your application to enter both Tweets and SMS. You want to use the same class for both, BUT tweets have a character limit of 140 and SMS have a character limit of 160 (we will pretend that we are still in the 90s).</p>
<p>So we need to create a delegate that asks for the character limit.<br />
<code></p>
<p>- (NSInteger) charachterLimitForTextView: (OBCTextView *)textView;<br />
</code></p>
<p>As mentioned before this should be declared as a protocol<br />
<code><br />
@protocol OBCTextViewDelegate</p>
<p>- (NSInteger) charachterLimitForTextView: (OBCTextView *)textView;</p>
<p>@end<br />
</code></p>
<p>The OBCTextView would call this method like so:</p>
<p><code></p>
<p>-(void)askDelegateForCharachterLimit{</p>
<p>NSInterger charachterLimit = [delegate charachterLimitForTextView:self];</p>
<p>//Do something with character limit</p>
<p>}</p>
<p></code></p>
<p>In our SMS view controller we would declare that we implement the delegate protocol.<br />
<code></p>
<p>@interface OBCSMSViewController : UIViewController < OBCTextViewDelegate > {</p>
<p>}</p>
<p>@end<br />
</code></p>
<p>And then in the implementation file you would implement the following method<br />
<code></p>
<p>- (NSInteger) charchterLimitForTextView: (OBCTextView *)textView{<br />
       return 160;<br />
}</p>
<p></code></p>
<p>This method is required for OBCTextView to work so we should also add the key word <strong>@required</strong> to the protocol</p>
<p><code><br />
@protocol OBCTextViewDelegate</p>
<p>@required<br />
- (NSInteger)charchterLimitForTextView:(OBCTextView *)textView;</p>
<p>@end<br />
</code></p>
<p><strong>Optional methods</strong></p>
<p>In your delegate, you may also want to implement optional methods. So for this example we will ask for the text color. You can specify that a method is optional using <strong>@optional</strong>.</p>
<p>@protocol OBCTextViewDelegate</p>
<p>@required<br />
- (NSInteger)charachterLimitForTextView:(OBCTextView *)textView;</p>
<p>@optional<br />
- (UIColor *)textViewColorForTextView:(OBCTextView *)textView;</p>
<p>@end</p>
<p>As it is optional the delegate class (helper object), does not have to implement it. If it does not implement it, and we attempt to call it, the application will crash. So how do we know if we should call the method or not ? The answer is <em>respondsToSelector</em>.</p>
<p><em>respondsToSelector</em> allows you to ask an object at run time, if it implements a given selector. So for our example:</p>
<p><code></p>
<p>-(void)getTextColor{<br />
if( [delegate respondsToSelector: @selector(textViewColorForTextView:)] ){<br />
UIColor *textColor = [delegate textViewColorForTextView:self];<br />
//Do something with the text color</p>
<p>}</p>
<p>}</p>
<p></code></p>
<p>if your class wants to return a textview color, then you simply implement the method.</p>
<p><code></p>
<p>- (NSInteger)textViewColorForTextView:(OBCTextView *)textView{<br />
       return [UIColor redColor];<br />
}</p>
<p></code></p>
<p>So that finishes off this post on helper objects, and how you can create your own. As always this example was a simple one to make it easy to follow. You could probably implement the above using setter methods.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/06/14/helper-objects-delegate-and-datasource/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>NSNumber: What is the point ?</title>
		<link>http://objcolumnist.com/2009/05/31/nsnumber-what-is-the-point/</link>
		<comments>http://objcolumnist.com/2009/05/31/nsnumber-what-is-the-point/#comments</comments>
		<pubDate>Sun, 31 May 2009 11:52:23 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=58</guid>
		<description><![CDATA[The first time you see NSNumber your probably say to yourself  &#8220;What is the point of NSNumber? I already have int, float, double etc&#8221;. Although this may be true, there are many occasions when you actually need to use NSNumber.
1. Adding a number to an array
NSArray (NSMutableArray etc) does not allow you to add [...]]]></description>
			<content:encoded><![CDATA[<p>The first time you see NSNumber your probably say to yourself  &#8220;What is the point of NSNumber? I already have int, float, double etc&#8221;. Although this may be true, there are many occasions when you actually need to use NSNumber.</p>
<p><strong>1. Adding a number to an array</strong></p>
<p>NSArray (NSMutableArray etc) does not allow you to add primitive types to it. This is because an NSArray is simple a set of pointers to the <strong>Objects</strong> you add to it. This means if you want to add a number to the array, you first have to wrap it in a NSNumber.</p>
<p><code><br />
NSArray *numbers=[NSArray arrayWithObject:[NSNumber numberWithInteger:2]];<br />
</code></p>
<p><strong>2. Number type conversion</strong></p>
<p>NSNumber allows you to easily convert the type of a number e.g. from an int to a float</p>
<p><code><br />
NSNumber *number=[NSNumber numberWithInteger:2];</p>
<p>float floatValue = [number floatValue];<br />
</code></p>
<p><strong>3. Perform selector calls</strong></p>
<p>Once you have used Objective-C for a while you may come across <code>performSelector</code>. This allows you to carry out advanced techniques like performing a selector after a given delay.<br />
<code><br />
[magicObject performSelector:@selector(performMagicWithNumber:) withObject:[NSNumber numberWithInteger:2] afterDelay:1.0];	</p>
<p></code></p>
<p>This the equivilant of doing the following without a delay:<br />
<code><br />
[magicObject performMagicWithNumber: [NSNumber numberWithInteger:2] ];<br />
</code><br />
<strong>4. Persisting Objects (CoreData)</strong></p>
<p>Archiving Objects is a lot easier than archiving primitive types, as NSNumber inherits from NSObject you can use various archiving and de-archiving methods on them. CoreData actually requires you to use NSNumber for persistent storage. One thing that may not be obvious at first glance, is that CoreData (and Objective-C) considers BOOL as a NSNumber.</p>
<p><strong>Summary:</strong></p>
<p>You may write the best selling application on the Appstore and never use NSNumber, but if you need to persist your objects or you need access to the various performSelector calls, NSNumber is obviously the way to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/05/31/nsnumber-what-is-the-point/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Make your iPhone vibrate</title>
		<link>http://objcolumnist.com/2009/05/23/make-your-iphone-vibrate/</link>
		<comments>http://objcolumnist.com/2009/05/23/make-your-iphone-vibrate/#comments</comments>
		<pubDate>Sat, 23 May 2009 20:27:58 +0000</pubDate>
		<dc:creator>Spencer MacDonald</dc:creator>
				<category><![CDATA[Quick Tip]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://objcolumnist.com/?p=56</guid>
		<description><![CDATA[One thing that took me a while to find out, was how to make an iPhone vibrate. In the end I found out that it is in the audio APIs, and it is just the one line of code.

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

]]></description>
			<content:encoded><![CDATA[<p>One thing that took me a while to find out, was how to make an iPhone vibrate. In the end I found out that it is in the audio APIs, and it is just the one line of code.</p>
<p><code><br />
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://objcolumnist.com/2009/05/23/make-your-iphone-vibrate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
