<?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>Indie iPhone Development Blog &#187; cocoa</title>
	<atom:link href="http://blog.indieiphonedev.com/tag/cocoa/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.indieiphonedev.com</link>
	<description>The musings of an independent iPhone developer</description>
	<lastBuildDate>Mon, 20 Jun 2011 18:48:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Getting the timezone on the device</title>
		<link>http://blog.indieiphonedev.com/2011/01/09/getting-the-timezone-on-the-device/</link>
		<comments>http://blog.indieiphonedev.com/2011/01/09/getting-the-timezone-on-the-device/#comments</comments>
		<pubDate>Sun, 09 Jan 2011 20:02:41 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[iPhone app]]></category>
		<category><![CDATA[objective-C]]></category>
		<category><![CDATA[source code]]></category>
		<category><![CDATA[timezone]]></category>

		<guid isPermaLink="false">http://blog.indieiphonedev.com/?p=258</guid>
		<description><![CDATA[Since the LogYourRun iPhone application will show you your running data in week and month views it is necessary to know the timezone of the user in order to bring up the data for the correct week/month. At first I thought I could use the NSDateFormatter to do this. The documentation says that you can [...]]]></description>
			<content:encoded><![CDATA[<p>Since the LogYourRun iPhone application will show you your running data in week and month views it is necessary to know the timezone of the user in order to bring up the data for the correct week/month.  At first I thought I could use the NSDateFormatter to do this.  The documentation says that you can get timezone informationby using %z or %Z as the format.  The %z should get you the offset in hours while the %Z should get you the name.  However when tested it turned out that the opposite is the case&#8230; </p>
<p>The following code gets you the timezone offset in hours:</p>
<pre class="brush: objc; title: ; notranslate">
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@&quot;Z&quot;]; // error in documentation - the zone in hours should be 'z' not 'Z'
timezoneoffset = (int) [[dateFormatter stringFromDate:[NSDate date]] intValue]/100;
DLog(@&quot;format %@&quot;, [dateFormatter stringFromDate:[NSDate date]]);
[dateFormatter release];
</pre>
<p>(Note the division by 100 is because the timezone is reported in military time so for 30 min offset the final timezone would be read as x.30 which is not really correct &#8211; but for getting a ballpark figure it would suffice).</p>
<p>Since the code is not behaving according to documentation it is not a good idea to use this to get the timezone because the code will break if the code ever starts behaving according to documentation.  </p>
<p>Instead it turns out that there is a very nice NSTimeZone object which will give you the timezone offset from GMT in seconds:</p>
<pre class="brush: objc; title: ; notranslate">
int timezoneoffset = ([[NSTimeZone systemTimeZone] secondsFromGMT] / 3600);
</pre>
<p>Then all you have to do to get the hour difference is divide by 3600 (seconds per hour).  If you cared about the half hour offsets you would make this a float &#8211; but this is plenty for getting a ballpark figure.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.indieiphonedev.com%2F2011%2F01%2F09%2Fgetting-the-timezone-on-the-device%2F&amp;title=Getting%20the%20timezone%20on%20the%20device" id="wpa2a_2"><img src="http://blog.indieiphonedev.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.indieiphonedev.com/2011/01/09/getting-the-timezone-on-the-device/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using audio services to play alert sound</title>
		<link>http://blog.indieiphonedev.com/2010/03/22/using-audio-services-to-play-alert-sound/</link>
		<comments>http://blog.indieiphonedev.com/2010/03/22/using-audio-services-to-play-alert-sound/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 04:24:36 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[iPhone app]]></category>
		<category><![CDATA[objective-C]]></category>
		<category><![CDATA[sounds]]></category>
		<category><![CDATA[source code]]></category>

		<guid isPermaLink="false">http://blog.indieiphonedev.com/?p=150</guid>
		<description><![CDATA[Some times it your application may inadvertently quit with out the user meaning to quit your app.  For example people run with the running/GPS app and the iPhone may be in a pocket / arm band / hand where the square button could be pressed unintentionally.  If the app quits while running it will not [...]]]></description>
			<content:encoded><![CDATA[<p>Some times it your application may inadvertently quit with out the user meaning to quit your app.  For example people run with the running/GPS app and the iPhone may be in a pocket / arm band / hand where the square button could be pressed unintentionally.  If the app quits while running it will not collect running data for the rest of the run and the user will be very disappointed.  To avoid this I have setup an alert which will make a sound if the user quits the app while the app is collecting running data.  I was able to find the original apple alert aiff files via Google and I chose to implement the Indigo sound as the alert &#8211; the cricket is not really loud enough to be an alert sound.</p>
<p>By implementing the playback of the sound as an alert sound the sound will be played even on the 1st gen iPod Touch which does not have a speaker.  Alert sounds can also be set to finish playback after the app finishes &#8211; which is an important feature for this use.  I was able to find how to set this property on <a href="http://nagano.monalisa-au.org/?p=721">Nagano&#8217;s blog</a>.  Not sure what most of the page says but the language of Objective C is universal. Remember to add the audiotoolbox to your project.</p>
<pre class="brush: objc; title: ; notranslate">

#include &amp;lt;AudioToolbox/AudioToolbox.h&amp;gt;
</pre>
<p>I then load the sound in the viewDidLoad init function for the view controller where I want to play the sound &#8211; this way you are not trying to load the sound as the app is quitting.  The soundFileObject isa global for this VC.</p>
<pre class="brush: objc; title: ; notranslate">
// SOUNDS
 NSString *path = [[NSBundle mainBundle] pathForResource:@&amp;quot;Indigo&amp;quot; ofType:@&amp;quot;aiff&amp;quot;];
 NSURL *fileURL = [NSURL fileURLWithPath:path];

 OSStatus err;
 err = AudioServicesCreateSystemSoundID((CFURLRef)fileURL, &amp;amp;soundFileObject);
 if(err) {
   DLog(@&amp;quot;AudioServicesCreateSystemSoundID err = %d&amp;quot;,err);
   exit(1);
 }

 UInt32 flag = 1;
 err = AudioServicesSetProperty(kAudioServicesPropertyCompletePlaybackIfAppDies,
     sizeof(UInt32),
     &amp;amp;soundFileObject,
     sizeof(UInt32),
     &amp;amp;flag);
 if(err){
   DLog(@&amp;quot;AudioServicesSetProperty err = %d&amp;quot;,err);
 }
</pre>
<p>Then under viewWillDisappear I have the following:</p>
<pre class="brush: objc; title: ; notranslate">
 if (runActivity.isStarted) {
   // play alert sound if exiting while running
   AudioServicesPlayAlertSound (self.soundFileObject);
 }
</pre>
<p>This way the sound will play if the view is unloading while the user is expecting the app to be collecting data.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.indieiphonedev.com%2F2010%2F03%2F22%2Fusing-audio-services-to-play-alert-sound%2F&amp;title=Using%20audio%20services%20to%20play%20alert%20sound" id="wpa2a_4"><img src="http://blog.indieiphonedev.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.indieiphonedev.com/2010/03/22/using-audio-services-to-play-alert-sound/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebKitErrorDomain error 101</title>
		<link>http://blog.indieiphonedev.com/2010/02/19/webkiterrordomain-101/</link>
		<comments>http://blog.indieiphonedev.com/2010/02/19/webkiterrordomain-101/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 00:48:21 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[error code]]></category>
		<category><![CDATA[iPhone app]]></category>
		<category><![CDATA[objective-C]]></category>
		<category><![CDATA[source code]]></category>

		<guid isPermaLink="false">http://blog.indieiphonedev.com/?p=136</guid>
		<description><![CDATA[The LogYourRun app uses both UIWebView and NSURLRequest to communicate with the LogYourRun database.  To let users upload and access their data.  These requests often contain fields that the user enter such as running notes, distance, time etc.  I had the WebKitErrorDomain 101 error come up on occasions when users tried to send requests that [...]]]></description>
			<content:encoded><![CDATA[<p>The LogYourRun app uses both UIWebView and NSURLRequest to communicate with the LogYourRun database.  To let users upload and access their data.  These requests often contain fields that the user enter such as running notes, distance, time etc.  I had the WebKitErrorDomain 101 error come up on occasions when users tried to send requests that contained spaces that were not properly encoded.  I was not able to find any documentation on this error so it took a while to figure out what was going on.</p>
<div id="attachment_137" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.indieiphonedev.com/wp-content/uploads/2010/02/webkiterror.png"><img class="size-medium wp-image-137" title="webkiterror" src="http://blog.indieiphonedev.com/wp-content/uploads/2010/02/webkiterror-300x172.png" alt="" width="300" height="172" /></a><p class="wp-caption-text">WebKitErrorDomain error 101</p></div>
<p>Once I identified that the issue was that some users had a space in their username it is a very easy fix.  Just use the stringByAddingPercentEscapesUsingEncoding function to have the string properly encoded:</p>
<pre class="brush: objc; title: ; notranslate">
[username stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding];
</pre>
<p>So if you come along a WebKitErrorDomain 101 error &#8211; take a look at the URL you are trying to submit and see if all the parts of it are properly encoded.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.indieiphonedev.com%2F2010%2F02%2F19%2Fwebkiterrordomain-101%2F&amp;title=WebKitErrorDomain%20error%20101" id="wpa2a_6"><img src="http://blog.indieiphonedev.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.indieiphonedev.com/2010/02/19/webkiterrordomain-101/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How the LogYourRun App switches between pedometer and GPS mode</title>
		<link>http://blog.indieiphonedev.com/2010/01/24/how-the-logyourrun-app-switches-between-pedometer-and-gps-mode/</link>
		<comments>http://blog.indieiphonedev.com/2010/01/24/how-the-logyourrun-app-switches-between-pedometer-and-gps-mode/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 03:36:29 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[iPhone app]]></category>
		<category><![CDATA[objective-C]]></category>
		<category><![CDATA[source code]]></category>

		<guid isPermaLink="false">http://blog.indieiphonedev.com/?p=49</guid>
		<description><![CDATA[The LogYourRun application tracks distance traveled by using the GPS as well as by using the accelerometer as a pedometer. This allows the application to measure distance even when GPS reception is not available &#8211; so on those cold mornings you do not have to wait around for the iPhone to get good GPS reception [...]]]></description>
			<content:encoded><![CDATA[<p>The LogYourRun application tracks distance traveled by using the GPS as well as by using the accelerometer as a pedometer. This allows the application to measure distance even when GPS reception is not available &#8211; so on those cold mornings you do not have to wait around for the iPhone to get good GPS reception before starting your run &#8211; once GPS reception becomes adequate the GPS takes over from the pedometer.</p>
<p>The application exist in two states:</p>
<p>1) Record distance using GPS</p>
<p>2) Record distance using pedometer</p>
<p>Switching from pedometer to GPS is instant &#8211; once GPS signal is adequate distance is now recorded using GPS.</p>
<p>Switching from GPS to pedometer will occur if an adequate GPS signal has not been received over a period of 20 seconds.  At this point the pedometer will take over calculating the distance and since it had not been recording distance for the previous 20 seconds the pedometer will calculate the distance that was traveled over those 20 seconds by rolling up the number of steps that were taken since the last good GPS signal was received.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/J7S0R8gYm4c&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/J7S0R8gYm4c&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.indieiphonedev.com%2F2010%2F01%2F24%2Fhow-the-logyourrun-app-switches-between-pedometer-and-gps-mode%2F&amp;title=How%20the%20LogYourRun%20App%20switches%20between%20pedometer%20and%20GPS%20mode" id="wpa2a_8"><img src="http://blog.indieiphonedev.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.indieiphonedev.com/2010/01/24/how-the-logyourrun-app-switches-between-pedometer-and-gps-mode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Encoding latitude and longitude the Google way</title>
		<link>http://blog.indieiphonedev.com/2010/01/22/encoding-latitude-and-longitude-the-google-way/</link>
		<comments>http://blog.indieiphonedev.com/2010/01/22/encoding-latitude-and-longitude-the-google-way/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 01:07:34 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[google polyline]]></category>
		<category><![CDATA[objective-C]]></category>
		<category><![CDATA[source code]]></category>

		<guid isPermaLink="false">http://blog.indieiphonedev.com/?p=15</guid>
		<description><![CDATA[The LogYourRun iPhone App uses the GPS functionality of the iPhone to track running distance as well as the running route.  When data is uploaded from the app to the website the list of GPS coordinates have to be transferred from the phone to the website.  Since I already store route GPS data on the [...]]]></description>
			<content:encoded><![CDATA[<p>The LogYourRun iPhone App uses the GPS functionality of the iPhone to track running distance as well as the running route.  When data is uploaded from the app to the website the list of GPS coordinates have to be transferred from the phone to the website.  Since I already store route GPS data on the LogYourRun website as an encoded Google polyline I decided to have the iPhone encode the GPS data before sending to the website.  This takes processing load off the server and allows for faster transfer of data from the iPhone to the website.</p>
<p>I already have a JavaScript and a PHP version of the functions that both encode and decode GPS data as a Google polyline &#8211; so it was just a matter of converting the functions to Objective-C / Cocoa.</p>
<p>The way that the encoder works is first it multiples the coordinate by 10e5, takes the floor value and compares it to the coordinate to the 10e5 value of the previous coordinate and encodes the difference between the two points.  The following are functions used to perform the basic math.</p>
<p>This function is used to multiply the coordinate by 10e5:</p>
<pre class="brush: objc; title: ; notranslate">
- (int) floor1e5: (double) coordinate {
 return (int) floor(coordinate * 1e5);
}
</pre>
<p>This function is used to encode a signed number:</p>
<pre class="brush: objc; title: ; notranslate">
- (NSString *) encodeSignedNumber: (int) num {
int sgn_num = num &lt;&lt; 1;
 if (num &lt; 0) {
 sgn_num = ~(sgn_num);
 }
 return [self encodeNumber: sgn_num];
}
</pre>
<p>And this function is used to encode an unsigned int:</p>
<pre class="brush: objc; title: ; notranslate">
- (NSString *) encodeNumber: (int) num {
 int nextValue;
 NSMutableString *encodeString = [[NSMutableString alloc] initWithCapacity:5];
 [encodeString autorelease];

 while (num &amp;gt;= 0x20) {
 nextValue = (0x20 | (num &amp;amp; 0x1f)) + 63;
 [encodeString appendFormat:@&quot;%c&quot;, ((char) (nextValue))];
 num &amp;gt;&amp;gt;= 5;
 }

 num += 63;
 [encodeString appendFormat:@&quot;%c&quot;, ((char) (num))];

 return encodeString;
}
</pre>
<p>The following function is used to encode an array of CoreLocation objects (CLLocation *).  This array is called <em>locations</em> in the following code.  The  first thing the function does is to make sure that there are points in our <em>locations</em> assay.  Next I setup a mutable string which is going to contain the encoded polyline string as well as a temporary CoreLocation object (<em>tmploc</em>).  Since we have not started going through the locations we set the previous latitude and longitude to 0 each (<em>plat</em> and <em>plng</em>).  Then I go through the <em>locations</em> array and put them into the <em>temploc</em>.  For each location the previous latitude and longitude is subtracted from the current after the 1e5 conversion.  The encoded latitude and longitude are then added to the encoded polyline string which is returned at the end of the function.</p>
<pre class="brush: objc; title: ; notranslate">
- (NSString *) googlePolyline {
 int i, late5, lnge5, dlat, dlng, plat, plng;

 if ([locations count] == 0) {
 return @&quot;&quot;;
 }

 NSMutableString *encodedPoints = [[NSMutableString alloc] initWithCapacity:100];
 [encodedPoints autorelease];
 CLLocation *tmploc;

 plat = 0;
 plng = 0;

 for (i = 0; i &amp;lt; [locations count]; i++) {
 tmploc = [locations objectAtIndex:i];

 late5 = [self floor1e5: tmploc.coordinate.latitude];
 lnge5 = [self floor1e5: tmploc.coordinate.longitude];

 dlat = late5 - plat;
 dlng = lnge5 - plng;

 plat = late5;
 plng = lnge5;

 [encodedPoints appendFormat:@&quot;%@%@&quot;, [self encodeSignedNumber:dlat], [self encodeSignedNumber:dlng]];

 }
 return [[[NSString alloc] initWithFormat: @&quot;%@&quot;, encodedPoints] autorelease];
}
</pre>
<p>The googlePolyline function can be used to convert an array of location objects to a simple string which can then applied directly to a google map.</p>
<p>For other ports of the google polyline encoder see:</p>
<p><a href="http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/" target="_blank">http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.indieiphonedev.com%2F2010%2F01%2F22%2Fencoding-latitude-and-longitude-the-google-way%2F&amp;title=Encoding%20latitude%20and%20longitude%20the%20Google%20way" id="wpa2a_10"><img src="http://blog.indieiphonedev.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.indieiphonedev.com/2010/01/22/encoding-latitude-and-longitude-the-google-way/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

