<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>ran-dom cocoa bits I use, come across, like, hate, the whole shebang.</description><title>cocoa-dom</title><generator>Tumblr (3.0; @cocoa-dom)</generator><link>http://cocoa-dom.tumblr.com/</link><item><title>NSHipster</title><description>&lt;p&gt;If you have anything to do with Cocoa: Go ahead and go to &lt;a href="http://nshipster.com"&gt;NSHipster&lt;/a&gt; now, if you haven&amp;#8217;t done so. I can&amp;#8217;t stress enough how good this site is in revealing great Stuff about Objective-C and the Cocoa and UIKit frameworks. Just so well done.&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/41856524731</link><guid>http://cocoa-dom.tumblr.com/post/41856524731</guid><pubDate>Wed, 30 Jan 2013 04:32:42 -0500</pubDate></item><item><title>Turn Based Gaming - Game Center Style Part #1</title><description>&lt;p&gt;Some of you may have noticed that we released &lt;a href="http://lostcitiesapp.com/"&gt;Lost Cities&lt;/a&gt; in the end of August. Apart from being our first card game (we did &lt;a href="http://carcassonneapp.com/"&gt;Carcassonne&lt;/a&gt; prior to that), it is also our first time to use the Turn Based API that Game Center provides starting with iOS 5.0. This sadly has proven a very challenging thing to do, and I want to part with some of the major gripes we encountered in this multipart series.&lt;/p&gt;
&lt;h3&gt;Game Center’s idea of Push Notifications&lt;/h3&gt;
&lt;p&gt;Push notifications are something iOS users are pretty familiar with now. They also made the hop to the desktop in Mountain Lion. Every app can send push notifications to the user in appropriate moments, if the user gives their permission. Users can even customize them on a per app basis and set if they want them to appear as alerts, banners and/or in the lock screen, if they have sound or not or they should badge the App Icon.&lt;/p&gt;
&lt;p&gt;All right, these are nice and understandable, already a little bit complicated – but okay. And if you are using the Game Center Turn Based API you get push notifications too. Isn’t that nice? Or so it seems. The Game Center Push Notifications sadly have some strangeness to them:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;strong&gt;They aren’t yours&lt;/strong&gt; – meaning they do not belong to the app sending it. They appear with the Game Center Icon and your App’s Name. The push notifications appear in Quotes to discern them from other Game Center Notifications. If you can search the web for &lt;a href="http://www.alexcurylo.com/blog/2012/01/02/tip-custom-game-center-sound/"&gt;undocumented features&lt;/a&gt; you can change the built in fanfare to your app’s sound. That’s it. (rdar://&lt;span&gt;10177685)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;They are all or nothing&lt;/strong&gt; – your users can’t set the notification settings for your app, they have to set the one’s for game center. You read right. You can’t turn them on or off for specific games, or even discern them from the Game Center’s friend requests. You want a Sound for this game notification? Then you also have to live with the friend request fanfare. You have a game you play only on your iPhone and not on your iPad? Too bad for you, can’t tell the iPad not to show the notifications. (rdar://&lt;span&gt;10177685)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Invitations to games appear during your game&lt;/strong&gt; - yes that too. If you are invited to a new game, while already in that game’s app, you get the invite notification banner shown inside your app. Also: there is no sane way of showing the invite text to you other than show in notification center, as we the app devs don’t have access to it. We don’t even get a notification.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No extra payload and early access for you&lt;/strong&gt; - with normal push notifications you, as an app, can add a little bit of extra payload to that notification which you get instantly when your app is moved into foreground or started. This way you can prepare the correct UI for the Notification the user swiped upon while you sneakily load the data you need in addition that in the background to give the fastes experience. Not so with Game Center. With Game Center you aren’t told at all that the user swiped on a notification to start your app. The earliest you can guess that the user swiped a notification is in the turn based delegate callback, which only fires after the Game Center Greeting Banner (you know the one) is shown in your app, which can be up to 30 seconds in bad networking conditions. And which also fires if you start the app and a turn is received during that time. So we more or less have to guess if the user swiped a notification instead of knowing. (rdar://&lt;span&gt;10177254)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;They aren’t localizable&lt;/strong&gt; – yes you read right – there is no sane way of localizing the Notifications. There isn’t even a proper way to set the notification text directly. (rdar://&lt;span&gt;9581651)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can either chose to not set a custom text in which case the recipient(s) of the push notification get a message of “Your Turn” localized in their iOS Language. But then you have no additional information about the game in progress, no opponents, no turn order, no score, no whatsoever.&lt;/p&gt;
&lt;p&gt;Or the participant that made the last move may set a text to be sent instead. This is the text that will be displayed in quotes in the notification. E.g. we chose to set “20 cards against Monkeydom”. This is the Status text of the game. Which poses a problem if you use the standard Game Center Turn based UI, as it appears in that list as status of the user that made the turn. So if you are using that you already have the issue of a strange display.&lt;/p&gt;
&lt;p&gt;However if you want to go the extra mile and localize the Message then the only thing you can do is the following: The participant app that makes a move needs to anticipate the recipient of the push notification (e.g. the next player), localize the notification in their language, and set the text and make the move. This needs knowledge about the locale of the recipient, which in turn you have to transport in the game data. We chose that approach, but it was a serious pain.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Although I’m sure some of the issues are adressed in iOS 6, I already know of some that aren’t. Which in turn means one more year until we can hope for improvements again.&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/30884242704</link><guid>http://cocoa-dom.tumblr.com/post/30884242704</guid><pubDate>Tue, 04 Sep 2012 16:00:20 -0400</pubDate></item><item><title>"One of the reasons that you may want to upgrade to Xcode 4.4 is that it includes Apple LLVM compiler..."</title><description>“One of the reasons that you may want to upgrade to Xcode 4.4 is that it includes Apple LLVM compiler 4.0 that adds a number of new Objective-C Language features. Even better most of the new features are backwardly compatibile with older versions of iOS. To make is easier to understand which features are available for which tool and OS releases Apple has published a useful Objective-C Feature Availability Index.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;h1 class="entry-title"&gt;Great summary on useyourloaf.com about &lt;a href="http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html"&gt;Automatic Property Synthesis With Xcode 4.4&lt;/a&gt;&lt;/h1&gt;&lt;/em&gt;</description><link>http://cocoa-dom.tumblr.com/post/28523015408</link><guid>http://cocoa-dom.tumblr.com/post/28523015408</guid><pubDate>Wed, 01 Aug 2012 21:16:51 -0400</pubDate></item><item><title>iPad Mini</title><description>&lt;p&gt;Just to go on the record: If and when an iPad mini comes I predict it will have the 1024x768 @1x resolution cramped into that smaller display area. It will have slightly higher DPI than the original iPad/iPhone, but it won&amp;#8217;t be Retina. All iPad apps will just work. All iPad apps that disregarded Human Interface Guidlines and made their buttons too small will have issues. All others will be a little bit more intricate to handle than on the iPad/iPad2, but be fine overall.&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/26545704798</link><guid>http://cocoa-dom.tumblr.com/post/26545704798</guid><pubDate>Thu, 05 Jul 2012 03:05:35 -0400</pubDate></item><item><title>Games, iCloud and Game Center</title><description>&lt;p&gt;There is a dilemma Game Developers face on iOS in terms of synced game state across multiple devices. This also applies to games that you deleted from the device once and want to continue playing some time in the future.&lt;/p&gt;
&lt;p&gt;Apple&amp;#8217;s recommended solution is to use the iCloud. However the iCloud storage is not tied to your Game Center account. This causes some major problems:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;somebody logged into Game Center on a device that does not have his iCloud account simply doesn&amp;#8217;t get his/her save games / game state (little known fact: you can log into the game center on any device using your account)&lt;/li&gt;
&lt;li&gt;since the iCloud account and the Game Center account are totally independet, there is no way of telling the user about this fact gracefully, so you end up just creating a new game state for this game center id on this iCloud storage, everyone is confused&lt;/li&gt;
&lt;li&gt;you essentiallly have to design your app around the fact that the user might have an iCloud account or not, and might have a Game Center account and not, and any combination of iCloud account and Game Center account, and work fine and predictable in every case. This adds very uneccessary complexity to quite a simple problem: taking care of the users progress in the best possible way.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;However, there would be a simple solution to this dilemma: make Game Center provide storage that is tied to the Game Center account. That is the natural fit. Users would get what they expect. If you think so too, please file a duplicate of rdar://11263793 so we get this rather sooner than later.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Sadly, this is just one of the little details Apple did not figure out right with Game Center.&lt;/span&gt;&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/21270059376</link><guid>http://cocoa-dom.tumblr.com/post/21270059376</guid><pubDate>Tue, 17 Apr 2012 11:31:00 -0400</pubDate></item><item><title>TCMMyClassWithSingleton.sharedInstance</title><description>&lt;p&gt;PSA: I switched to dot syntax for Singletons now. Seems fitting, looks less cluttered. I took some time getting used to it, but now I really like it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[NSUserDefaults.standardUserDefaults boolForKey:@"SomeKey"];&lt;br/&gt;[NSNotificationCenter.defaultCenter postNotificationName…];&lt;/code&gt;&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/12462713126</link><guid>http://cocoa-dom.tumblr.com/post/12462713126</guid><pubDate>Mon, 07 Nov 2011 03:38:39 -0500</pubDate></item><item><title>Network Testing</title><description>&lt;p&gt;If you put in network code into your apps, it is always important to test against bad network conditions. While this isn&amp;#8217;t too trivial, it was always possible using dummynet.&lt;/p&gt;
&lt;p&gt;However, now new in Lion is a Preference pane to use, so you don&amp;#8217;t have any excuses anymore for not testing: &lt;a href="http://mattgemmell.com/2011/07/25/network-link-conditioner-in-lion"&gt;Network Link Conditioner&lt;/a&gt; - Use it and use it heavily - real life network conditions, especially on iOS, are never as good as in your pristine office big bad ass network location.&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/8041734755</link><guid>http://cocoa-dom.tumblr.com/post/8041734755</guid><pubDate>Mon, 25 Jul 2011 09:41:33 -0400</pubDate></item><item><title>Could the Mac become a Post-PC device?</title><description>&lt;p&gt;Today I did a little mind experiment thinking about if an ARM based MacBook Air would be viable, and what would be the pros and cons.&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Battery life&lt;/li&gt;
&lt;li&gt;Return to in house chip development&lt;/li&gt;
&lt;li&gt;iOS and Mac running on the same architectures&lt;/li&gt;
&lt;li&gt;Probably a good long term bet, as ARM is here to stay and winning the performance per watt battle&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;No Bootcamp, parallels or the such&lt;/li&gt;
&lt;li&gt;No Rosetta-like intel emulation for existing apps&lt;/li&gt;
&lt;li&gt;Probably less performant, although with enough Cores going on, probably not that big of an issue.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;However the more interesting point to me is that Apple is here to innovate. Mac OS X has kind of seen its time and iOS in itself is a good companion, but not a replacement. If they really want to change the way the standard computer works then a mandatory transition to another hardware platform could be the way.&lt;/p&gt;
&lt;p&gt;How could such a future look like:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;it would be one big step further in the direction Lion is taking. But since backwards compatibility is not an issue there, as developers would have to recompile and adjust to the hardware anyways, Apple could cut with old metaphors and really innovate. E.g. away with the standard file system. Away with the unix shell. Away with the Menubar. Keep technologies and infrastructure, but only expose the Developers to the new environment.&lt;/li&gt;
&lt;li&gt;redo AppKit from ground up, gone with the slapping on of technologies adapted from the iOS development, a real first class DesktopUIKit, give it the same love that the rewriting did for iOS, perfectly adapted to the new and improved interface metaphors.&lt;/li&gt;
&lt;li&gt;the platform would be closed in the same way that iOS is closed. Apps only via the App Store, nothing else. There is a clear incentive for Apple to do this, 30% of every sale made.&lt;/li&gt;
&lt;li&gt;the platform would include full support of iOS and iPad Apps out of the box. E.g. the platform would be comprised of a multiple of the iOS/iPad resolutions so multiple iOS apps could be used at once&lt;/li&gt;
&lt;li&gt;great integration of multitouch, both via the trackpad and also directly on the screen. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;In essence Apple would create a third platform between iOS and Mac and use it as an opportunity to implement major changes in the user interaction model. It could leverage the existing Developer base in the same way, or even more so than they did with iOS.&lt;/p&gt;
&lt;p&gt;The major flaw in that theory: This third platform really needs a good incentive for users to jump on. Something as &amp;#8220;magical&amp;#8221; as the iPad had. And I have no clue what that might be, but hey, that&amp;#8217;s just me, I also thought that Apple needed something special for an iPad to make sense. And all they needed was a great execution of the basic features, reduced to the max to chime in the Post-PC era. The next step: to make the Mac make the jump into the Post-PC era as well.&lt;/p&gt;
&lt;p&gt;So these are my 2 cents, here to stay to be laughed at in the future ;)&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/6017420404</link><guid>http://cocoa-dom.tumblr.com/post/6017420404</guid><pubDate>Mon, 30 May 2011 19:25:50 -0400</pubDate></item><item><title>0x8badf00d, Core Data and Migration</title><description>&lt;p&gt;Let&amp;#8217;s begin with the basics. In iOS there is a watchdog process - a watchdog that checks if an App takes more than about 20 seconds to start without getting back to the OS it will be killed. In the crash reports this killing is indicated by an exception code of 0x8badf00d - Ate Bad Food. Getting back to the OS more or less means that your delegate call of  application:didFinishLaunchingWithOptions: needs to return control to the runloop in time. If you don&amp;#8217;t: you are killed. The user experience of this is that your Default.png is shown for about 20 seconds, and then the iPhone/iPad returns to the home screen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Fun Fact:&lt;/em&gt;&lt;/strong&gt;&lt;em&gt; On iOS Devices that support multitasking the watchdog can be confused by pressing home and go back to the app again in intervals slightly less than 20 seconds. So if an App is showing this behavior, you might get it to work again using this stunt.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is all good and well, the user should not have to wait for more than 20 seconds for an App to actually do something that the user can see or interact with. This is where Core Data comes in.&lt;/p&gt;
&lt;p&gt;Core Data is a great framework that provides developers an abstraction to a local database. You do so by specifying a data model in Xcode, and provide classes for your database objects. In code you usually initialize your Core Data infrastructure very early on, because you rely on the data in the database for almost everything your app does. Usually that step takes little time - if the app is new you maybe want to copy an existing database as a first step, otherwise it just opens up the database files and returns.&lt;/p&gt;
&lt;p&gt;However, if you want to store additional information in your database, you need to update your model. And if you do so, you need to migrate your data once to accommodate the new model. This happens in that early on initialization step. As migration goes there are two kinds of migration: Lightweight migration and manual migration. Lightweight migration is fast and can be done by just issuing SQL statements to the underlying database. Manual migration causes every object to be loaded and be updated. If you can achieve your changes with lightweight migration, especially on iOS devices you should do so. However, sometimes it is necessary to do some manual work in the migration process.&lt;/p&gt;
&lt;p&gt;This is where the shit can hit the fan: Consider you are initializing Core Data before the end of  application:didFinishLaunchingWithOptions: because you want to use some of the existing data to prepare badges and UI state in the first viewWillAppear: methods of your top view controllers. Consider further that you are making a major update to your App and the database needs a manual migration. Now what easily can happen is that the watchdog literally bites your app in the ass.&lt;/p&gt;
&lt;p&gt;And even better, during development you probably won&amp;#8217;t notice. Why? Because of many reasons, I try to list many of them:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The watchdog is inactive if you are running in the debugger. Your App Start may take a while, but your app will always start up.&lt;/li&gt;
&lt;li&gt;The migration step only happens once, unless your specifically testing for it over and over again. And it is most likely that that step is done while you are running in the debugger to check if everything goes right.&lt;/li&gt;
&lt;li&gt;The data you need to test needs to be big. In most test and development scenarios you have realistic data, with a wide variety of items being in there to catch most cases, but you won&amp;#8217;t do very big data because that slows down overall roundtrip time.&lt;/li&gt;
&lt;li&gt;Your test devices most probably will be the fastest you have most of the time, again for roundtrip reasons. And faster devices migrate faster. Probably fast enough to not show the problem.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;When you look at the customers that will have that problem out there you see another problem: They are probably your best customers. If they store a lot of data in your app, they use it a lot. If there is a lot of data, migration takes long. Tada! Horrible.&lt;/p&gt;
&lt;p&gt;So now that we have established that this problem is a real turdball coming your way, how do you prevent/fix it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution #1&lt;/strong&gt;: do lightweight migration. If you can do that. This will be fast enough to not call the wrath of the Watchdog.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution #2&lt;/strong&gt;: if you can&amp;#8217;t do lightweight migration, make sure your migration step won&amp;#8217;t be caught by the watchdog. E.g. your initialization of Core Data needs to be done after the app has returned from the application:didFinishLaunchingWithOptions: callback. A really good way of testing this is adding a simple sleep(25) in the code that actually creates your persistentStoreCoordinator. That way without having all test data, migration always takes long enough to trigger the watchdog. And again be sure to not attach the debugger, or the watchdog won&amp;#8217;t bite.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lessons learned:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Beware of the watchdog.&lt;/li&gt;
&lt;li&gt;Core Data is great, but migration can really hit you quite unexpectedly.&lt;/li&gt;
&lt;li&gt;If you use Core Data - put in that sleep(25) call now and test if you get bitten. If so fix it so it won&amp;#8217;t bite you unprepared in the future when you update your model.&lt;/li&gt;
&lt;li&gt;Prepare feedback for user migration. As it turns out users don&amp;#8217;t make a difference between an app that appears frozen for a long period of time and an app that actually crashes. Even if migration will only happen once for each major model update, that moment can be crucial.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://cocoa-dom.tumblr.com/post/5835145215</link><guid>http://cocoa-dom.tumblr.com/post/5835145215</guid><pubDate>Wed, 25 May 2011 12:08:44 -0400</pubDate></item><item><title>"Didn’t we used to make fun of Eclipse for stuff like this?"</title><description>“Didn’t we used to make fun of Eclipse for stuff like this?”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;I could not agree more. (via &lt;a href="http://subjectiveobserver.wordpress.com/2011/03/26/a-picture-worth-a-thousand-pixels/"&gt;The Powers of Observation&lt;/a&gt;)&lt;/em&gt;</description><link>http://cocoa-dom.tumblr.com/post/4743946110</link><guid>http://cocoa-dom.tumblr.com/post/4743946110</guid><pubDate>Tue, 19 Apr 2011 06:24:50 -0400</pubDate></item><item><title>Be very careful when calling -[NSNotificationCenter removeObserver:]</title><description>&lt;p&gt;&lt;a href="http://rentzsch.tumblr.com/post/4412887910"&gt;rentzsch&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://subjective-objective-c.blogspot.com/2011/04/avoid-nsnotification-removeobserver.html"&gt;Samuel Défago&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Never ever use &lt;code&gt;-[NSNotificationCenter removeObserver:]&lt;/code&gt; to unregister from notification events, except from a dealloc method. This might cancel registrations made by a parent class, and you cannot know how a parent class is implemented (at least you shouldn’t care). Stick to this rule even if your parent class is NSObject: Your class hierarchy might change in the future, and you do not want to run into problems when you don’t have to, do you?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(via &lt;a href="https://twitter.com/0xced"&gt;Cédric Luthi&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strike&gt;I strongly disagree. There are multiple situation e.g. on the iPhone where registering and deregistering in the [will|did]Appear/Disappear: methods is valid, helpful and good style.&lt;/strike&gt; (And I took the liberty to fix the classname)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Permature posting is premature. (note to self: always read the whole referenced article). &lt;/p&gt;
&lt;p&gt;So to add some actual wisdom to this subject: Calling the -[NSNotificationCenter removeObserver:] should be confined to situations where you get rid of the object. So I agree dealloc can be the place, but it also can be somewhere up in the chain if you invalidate your object where you already have the knowledge it should go away, but it is not dealloced memory wise. In complex cocoa apps you run in these situations. Also helpful in these cases: [NSObject &lt;span&gt;cancelPreviousPerformRequestsWithTarget: self];&lt;/span&gt;&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/4412922047</link><guid>http://cocoa-dom.tumblr.com/post/4412922047</guid><pubDate>Thu, 07 Apr 2011 05:49:00 -0400</pubDate></item><item><title>UIEdgeInsets</title><description>&lt;p&gt;A common task for UIKit devs: Inset a CGRect by an amount from each edge:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UIEdgeInsetsInsetRect(rect,insets);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And to do that in one line of course the constructor of UIEdgeInsets&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UIEdgeInsetsMake(top,left,bottom,right);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Why on earth they decided to make the order of insets the other way round as CSS will remain a mysterie. Also note that a negative inset expands towards this edge. E.g.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UIEdgeInsetsInsetRect(CGRectMake(0,0,100,100), UIEdgeInsetsMake(10,10,-50,50));&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;results in the following CGRect: &lt;code&gt;{10,10,140,40}&lt;/code&gt;&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/3621206259</link><guid>http://cocoa-dom.tumblr.com/post/3621206259</guid><pubDate>Thu, 03 Mar 2011 11:17:17 -0500</pubDate></item><item><title>Great Summary of the Fast App Switching iOS4 livecycle of an App</title><description>&lt;a href="http://www.drobnik.com/touch/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/"&gt;Great Summary of the Fast App Switching iOS4 livecycle of an App&lt;/a&gt;</description><link>http://cocoa-dom.tumblr.com/post/904484410</link><guid>http://cocoa-dom.tumblr.com/post/904484410</guid><pubDate>Wed, 04 Aug 2010 17:12:00 -0400</pubDate></item><item><title>The hidden complexity of iOS 4 Multitasking </title><description>&lt;p&gt;Just a Quick list of what to keep in mind when designing your app with the new Fast App Switching in place:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;the entry point of your app might be anywhere and data may have changed. Even built in Apps like the Photos app get that one wrong. Have the Photos app open. Make new pictures. Go back. Or worse: download and delete all the fotos to iPhoto. Reopen the Photos app: crash.&lt;/li&gt;
&lt;li&gt;if something goes wrong, the app doesn&amp;#8217;t automatically stop and restart when the user presses home. This might seem obvious, but if there are edge cases where you mess up your navigation controller hierachy beyond repair that matters. This happens. The user needs to know how to kill your app in that case, and most don&amp;#8217;t. Be extra careful with that.&lt;/li&gt;
&lt;li&gt;besides the fast app switching way you still need to keep state and position in the app on your own for your next restart. For old devices as well as for when you get killed somewhere along the way. So you still need to do that. Defacto things got more complex instead of easier. However, if you do it right you might also have a good chance of being a good iOS 3.x citizen.&lt;/li&gt;
&lt;li&gt;if you listen to URLs or Push Notification you need to be prepared for getting them while already running. Worse: you need to detect this yourself using a combination of willEnterForeground and didBecomeActive, so you can handle things differently if you were active and not. Also in the URL case the possiblity exists you get called twice. See &lt;a href="http://twitter.com/chockenberry/status/17889156210"&gt;http://twitter.com/chockenberry/status/17889156210&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;network connections and hosting die when you get suspended. Be sure to reopen your server if you e.g. provide web access or something similar.&lt;/li&gt;
&lt;li&gt;your app might not restart for very long time periods, make sure you move important checks and tasks to willEnterForeground or didBecomeActive so they don&amp;#8217;t starve out. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;That&amp;#8217;s just a quick list of real world issues I encountered. I&amp;#8217;m sure there a lots more subtleties and edge cases. Be prepared!&lt;/p&gt;
&lt;p&gt;Update:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;if you have settings you need to make sure that changing those on the fly does work. e.g. the settings change can hit you in any place in your app and you need to be prepared and act like it. e.g. update lists, query the NSUserDefaults without caching, pp&lt;/li&gt;
&lt;li&gt;if opening an URL/push notification means you jump to another location in your app, the code handing that opening needs to be able to dismiss any - and i mean any - currently showing UI and present itself. This can be a very tough one.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Update 2:&lt;/p&gt;
&lt;p&gt;With all the issues involved, opting out by adding &lt;span&gt;UIApplicationExitsOnSuspend &lt;/span&gt;with a boolean value of YES to your Info.plist might be the better option if your app has great pre-iOS4 behaviour.&lt;/p&gt;
&lt;ul&gt;&lt;/ul&gt;</description><link>http://cocoa-dom.tumblr.com/post/866039292</link><guid>http://cocoa-dom.tumblr.com/post/866039292</guid><pubDate>Tue, 27 Jul 2010 09:34:00 -0400</pubDate></item><item><title>Separation of Tasks</title><description>&lt;p&gt;If you know me, you might know that I don&amp;#8217;t like Xcode&amp;#8217;s internal Documentation Viewer and don&amp;#8217;t use the internal editor. My reasons: I need my Tasks separated. Source files are in &lt;a href="http://www.codingmonkeys.de/subethaedit/index.html"&gt;SubEthaEdit&lt;/a&gt;, Project files, compilation, console feedback, debugger are in Xcode, Source control management is in the terminal, and Documentation is in &lt;a href="http://homepage.mac.com/aglee/downloads/appkido.html"&gt;AppKiDo&lt;/a&gt; (and &lt;a href="http://homepage.mac.com/aglee/downloads/appkido.html"&gt;AppKiDo-for-iPhone&lt;/a&gt;). Why? Quick and straight access. I hit the Xcode App Icon for a compile, AppKiDo for Documentation, etc. And they all remember their state. If I do all in Xcode then navigation becomes slow and cumbersome.&lt;/p&gt;
&lt;p&gt;But that all has a side effect: I&amp;#8217;m utterly lost in the time AppKiDo needs to catch up with the latest Xcode and documentation release if it breaks anything. Thanks to Andy Lee that is almost always a very very short period of time, but nevertheless makes me anxious all the time. That&amp;#8217;s why I really Appreciate a recent contender in the Documentation Viewing business: &lt;a href="http://fileability.net/ingredients/"&gt;Ingredients&lt;/a&gt;. It looks very nice and modern, but still lacks a few features I use in AppKiDo. Nevertheless: the more the merrier!&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/587661522</link><guid>http://cocoa-dom.tumblr.com/post/587661522</guid><pubDate>Mon, 10 May 2010 17:01:50 -0400</pubDate></item><item><title>great setup and extension tips for mercurial</title><description>&lt;a href="http://naleid.com/blog/2008/11/25/my-mercurial-setup-plus-some-useful-shims-and-jigs/"&gt;great setup and extension tips for mercurial&lt;/a&gt;</description><link>http://cocoa-dom.tumblr.com/post/535750034</link><guid>http://cocoa-dom.tumblr.com/post/535750034</guid><pubDate>Tue, 20 Apr 2010 09:28:00 -0400</pubDate></item><item><title>NSString stringWithFormat: - indexed arguments!</title><description>&lt;p&gt;A IMHO quite underused feature of the format string is indexed parameter referencing. Something that can&amp;#8217;t be found easily in the documentation sadly, but is quite crucial for good localization and can be also be used if you want to use an argument more than once: &lt;/p&gt;
&lt;p&gt;&lt;code&gt;NSString *formatString = @"Page %1$d of %2$d";&lt;br/&gt;[NSString stringWithFormat:formatString,5,120];&lt;br/&gt;// results in @"Page 5 of 120" &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you use the indexed argument list, then you can easily change the order the arguments are used:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NSString *formatString = @"Total Pages:%2$d - Current Page:%1$d";&lt;br/&gt;[NSString stringWithFormat:formatString,5,120];&lt;br/&gt;// results in @"Total Pages:120 - Current Page:5" &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Or even use one value twice, or not at all:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NSString *formatString = @"(Total Pages:%2$d) %1$d/%2$d";&lt;br/&gt;[NSString stringWithFormat:formatString,5,120];&lt;br/&gt;// results in @"(Total Pages:120) 5/120"&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This works with all types of placeholders, just inject n$ between the % and the actual type of the identifier. 1$ is the first argument, 2$ the second and so on.&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/493586464</link><guid>http://cocoa-dom.tumblr.com/post/493586464</guid><pubDate>Sat, 03 Apr 2010 12:21:23 -0400</pubDate></item><item><title>Choosing the right spot for your task</title><description>&lt;p&gt;Usually life with Cocoa is nice. You have hooks and handles for every occasion. However - sometimes you are not looking in the right place, or have no idea this hook you need exists at all.&lt;/p&gt;
&lt;p&gt;A strange and interesting example from SubEthaEdit is the &lt;code&gt;[NSAttributedString doubleClickAtIndex:]&lt;/code&gt; method. I had to ask for that at WWDC because I was sure this kind of functionality would either be named differently if put at the model level, or would be in &lt;code&gt;NSText&lt;/code&gt; or &lt;code&gt;NSTextView&lt;/code&gt;. However, there it is, quite misplaced, but there.&lt;/p&gt;
&lt;p&gt;Another case of using the right delegate callbacks on the iPhone is the &lt;code&gt;-[UIApplicationDelegate applicationDidFinishLaunching:]&lt;/code&gt; method. Coming from the desktop this is a no brainer, this is where you set up your application.&lt;/p&gt;
&lt;p&gt;However, with iPhone 3.0 things changed. There now is a new call,&lt;br/&gt;&lt;code&gt;-[UIApplicationDelegate application: didFinishLaunchingWithOptions:]&lt;/code&gt; which is called in preference of the aforementioned call. This is clearly stated in the &lt;code&gt;UIApplicationDelegate&lt;/code&gt; overview in the Documentation. However these are the intricacies you might miss if you are not watchful. Always stay on top of the API changes!&lt;/p&gt;
&lt;p&gt;And a last one: Make sure you understand what each hook means. Make sure you put your code in the right spot. Don&amp;#8217;t do stuff in &lt;code&gt;-awakeFromNib&lt;/code&gt; if there is a better location. E.g. if you are a &lt;code&gt;NSWindowController&lt;/code&gt;, &lt;code&gt;-awakeFromNib&lt;/code&gt; might get called twice, once for the nib it lives in, once for the nib it itself is loading. Use &lt;code&gt;-windowWillLoad&lt;/code&gt; and &lt;code&gt;-windowDidLoad&lt;/code&gt; instead. If you are an &lt;code&gt;NSView&lt;/code&gt; the &lt;code&gt;-viewWillMoveToSuperview:&lt;/code&gt;, &lt;code&gt;-viewDidMoveToSuperview&lt;/code&gt; methods may be more suited for setup than the init methods. &lt;/p&gt;
&lt;p&gt;Bottom line: make sure you understand the events you get called for and think about if this is the right place to put your code. If not, it is highly likely Cocoa has the right hook for you, you just don&amp;#8217;t know it. Think again of what kind of event it is you need do know about and look into the documentation. Don&amp;#8217;t forget to look into all notifications as well, some events only trigger those.&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/482553113</link><guid>http://cocoa-dom.tumblr.com/post/482553113</guid><pubDate>Mon, 29 Mar 2010 18:00:26 -0400</pubDate></item><item><title>Handy constants </title><description>&lt;p&gt;Another element that is easily overlooked, but can make code and life so much easier: Convenience Constants. Take some examples:&lt;/p&gt;
&lt;li&gt;&lt;code&gt;CGPointZero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectZero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGSizeZero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectInfinite&lt;/code&gt; - mostly used in Core Image contexts&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectNull&lt;/code&gt; - not equal to CGRectZero, returned by e.g. CGRectIntersection()&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NSNotFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGAffineTransformIdentity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIEdgeInsetsZero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UITrackingRunLoopMode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NSFoundationVersionNumber&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NSRunLoopCommonModes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NSEventTrackingRunLoopMode&lt;/code&gt;&lt;/li&gt;</description><link>http://cocoa-dom.tumblr.com/post/473512821</link><guid>http://cocoa-dom.tumblr.com/post/473512821</guid><pubDate>Thu, 25 Mar 2010 20:00:53 -0400</pubDate></item><item><title>Cocoa is object oriented, right?</title><description>&lt;p&gt;Of course it is. And greatly designed too if you ask me. However there is a huge world of regular functions and macros which you might have overlooked. Here are some of my favorites:&lt;/p&gt;
&lt;li&gt;&lt;code&gt;UIImagePNGRepresentation(image)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIImageJPEGRepresentation(image,quality)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIImageWriteToSavedPhotosAlbum(image,target,selector,context)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIInterfaceOrientationIsLandscape(orientation)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIInterfaceOrientationIsPortrait(orientation)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectIntegral(rect)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectInset(rect,dx,dy)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectOffset(rect,dx,dy)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectStandardize(rect)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectDivide(rect,*slice,*remainder,amount,edge)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectGetMidX(rect)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGRectGetMidY(rect)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MIN(A,B)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MAX(A,B)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NSStringFromSelector(aSelector)&lt;/code&gt;&lt;/li&gt;
&lt;p&gt;Look them up, they might prove useful, or just make your code easier to read!&lt;/p&gt;</description><link>http://cocoa-dom.tumblr.com/post/473106494</link><guid>http://cocoa-dom.tumblr.com/post/473106494</guid><pubDate>Thu, 25 Mar 2010 16:23:20 -0400</pubDate></item></channel></rss>
