<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 <title>Daniel Tull</title>
 <link href="http://danieltull.co.uk/atom.xml" rel="self"/>
 <link href="http://danieltull.co.uk/"/>
 <updated>2017-04-07T21:46:46+00:00</updated>
 <id>http://danieltull.co.uk/</id>
 <author>
   <name>Daniel Tull</name>
   <email>dt@danieltull.co.uk</email>
 </author>
 
 <entry>
   <title>The Hard Work Behind Running a Successful Community Event</title>
   <link href="http://danieltull.co.uk/blog/2016/02/20/the-hard-work-behind-running-a-successful-community-event/"/>
   <updated>2016-02-20T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2016/02/20/the-hard-work-behind-running-a-successful-community-event</id>
   <content type="html">&lt;p&gt;There was a mixup with the ticketing process for this week’s NSLondon event which has caused some complaints and discussion on its &lt;a href=&quot;http://www.meetup.com/NSLondon/events/228804148/&quot;&gt;event page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I ran the London iOS Developer Group (LiDG) for five years, putting on two 30 minute talks at the Apple Store, Regent Street almost every month. I never delegated out to anyone else and eventually I got really tired of chasing for presenters, chasing for slides, discussing date conflicts with the Apple Store, promoting the event via Lanyrd and twitter and still getting complaints.&lt;/p&gt;

&lt;p&gt;If anyone thinks that organising a large meetup with informative and entertaining talks is easy, I would encourage you to try to do so yourself.&lt;/p&gt;

&lt;p&gt;I have seen NSLondon rise up in the London iOS community from just before its inception. &lt;a href=&quot;https://twitter.com/daniel1of1&quot;&gt;Daniel Haight&lt;/a&gt; has put in an extended team over the last year which, as far as I can tell, has only recently become fully self functioning allowing him to take some likely much needed breaks from the hell that is organising an event.&lt;/p&gt;

&lt;p&gt;From my own experience, I can say that without this team, NSLondon just couldn’t be sustained by any one, no matter how much they loved and cared about their event.&lt;/p&gt;

&lt;p&gt;To me looking in, it seems like the ticketing mistake this week was &lt;em&gt;possibly&lt;/em&gt; caused by this new extended team.&lt;/p&gt;

&lt;p&gt;I am sure the much underpressured NSLondon team will &lt;em&gt;want&lt;/em&gt; to prevent this happening again more than any one commenting on the event page. This team is evolving, improving and learning. That’s the price we pay for continued events, because it sure hasn’t been with money over the years.&lt;/p&gt;

&lt;p&gt;If anyone thinks that organising a large meetup with informative and entertaining talks is easy, I would encourage you to try to do so yourself. Because it’s fun, invigorating, empowering, charitable, scary, frustrating, depressing, annoying and stressful.&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Not a Core Data error</title>
   <link href="http://danieltull.co.uk/blog/2015/11/20/not-a-core-data-error/"/>
   <updated>2015-11-20T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2015/11/20/not-a-core-data-error</id>
   <content type="html">&lt;p&gt;This morning I came across &lt;code class=&quot;highlighter-rouge&quot;&gt;SQLite error code:522, 'not an error’&lt;/code&gt; before seeing the app crash. Clearly not an error!&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;http://danieltull.co.uk/issues&quot;&gt;Issues&lt;/a&gt; I make use of Core Data and one thing I decided early on was to use its store as a cache only: All data in the Core Data store can be fetched again from the server. There were a couple of reasons for this choice:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It keeps me flexible to model changes, without the overhead of migration.&lt;/li&gt;
  &lt;li&gt;I could store user-created entities such as favourites, draft issues and draft comments in files NSCoding, which in turn allowed me to easily adopt CloudKit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a model change happens, I delete the store at the URL I gave and recreate a new one in its place.&lt;/p&gt;

&lt;p&gt;The problem above occurred for me because Core Data creates journaling files alongside the file I specify. When I delete the store, I don’t touch these files, mainly because there’s not really a way to know about them – they have the same filename prefix with &lt;code class=&quot;highlighter-rouge&quot;&gt;-wal&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;-shm&lt;/code&gt; appended, so I could delete all the files with the same filename prefix.&lt;/p&gt;

&lt;p&gt;An easier solution I saw was to create a directory at the URL and make the actual store inside that directory. This way, when I need to delete the store, I can remove the folder safely knowing that all the journaling files will be removed as well.&lt;/p&gt;

&lt;h2 id=&quot;update-26th-november-2015&quot;&gt;Update 26th November 2015&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://twitter.com/P373C&quot;&gt;Pete Callaway&lt;/a&gt; has pointed out to me that a method called &lt;code class=&quot;highlighter-rouge&quot;&gt;destroyPersistentStoreAtURL:withType:options:error:&lt;/code&gt; was added to NSPersistentStoreCoordinator in iOS 9 that deletes a store and its associated files.&lt;/p&gt;

&lt;p&gt;This should negate the need to try to guess what extra files Core Data or SQL might create now or in the future.&lt;/p&gt;

&lt;p&gt;It was also mentioned at &lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2015-220/?time=530&quot;&gt;WWDC this year&lt;/a&gt;.&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Removing Crashlytics and Google Analytics</title>
   <link href="http://danieltull.co.uk/blog/2015/11/16/removing-crashlytics-and-google-analytics/"/>
   <updated>2015-11-16T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2015/11/16/removing-crashlytics-and-google-analytics</id>
   <content type="html">&lt;p&gt;One of the beta releases of &lt;a href=&quot;http://danieltull.co.uk/issues&quot;&gt;Issues&lt;/a&gt; caused one of my testers to tweet:&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;&lt;p lang=&quot;und&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/danielctull&quot;&gt;@danielctull&lt;/a&gt; #238 yes!&lt;/p&gt;&amp;mdash; Lee Armstrong (&lt;a href=&quot;https://twitter.com/lesmond&quot;&gt;@lesmond&lt;/a&gt;) &lt;a href=&quot;https://twitter.com/lesmond/status/662897418724339712&quot;&gt;7 November 2015&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;This was in reference to a ticket I added to Issues’ tracker: &lt;strong&gt;#238: Remove Crashlytics&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Today version 1.1.2 was released without Crashlytics and after removing Google Analytics in version 1.1, I can now say Issues contains no tracking libraries. On Twitter this evening I received a couple of enquires as to why I had chosen to do this, so I thought I’d provide a little detail about it here.&lt;/p&gt;

&lt;h2 id=&quot;trust&quot;&gt;Trust&lt;/h2&gt;

&lt;p&gt;Issues has the potential to store very private and very secret information; from amazing new features for products, damning security bugs to just embarressing mess ups. These are generally the same reasons many companies choose to host their source code and bug trackers in house, and I have taken the decision that Issues will communicate with only the servers my users trust.&lt;/p&gt;

&lt;p&gt;I would like to just point out now that I have never &lt;em&gt;ever&lt;/em&gt; provided either Google Analytics or Crashlytics with any data from a connected bug tracker. I used the former to track sales and which screens were being hit and the latter for crash reporting.&lt;/p&gt;

&lt;p&gt;However, how can I expect my users to trust me on that? Trust is hard enough to win face-to-face, let alone when you’re only reading their words or perhaps have no contact at all.&lt;/p&gt;

&lt;p&gt;If someone at a highly secure company is considering Issues, I want to make sure the only network connections from my app are to their servers.&lt;/p&gt;

&lt;p&gt;Lets face it, both Google Analytics and Crashlytics are black boxes. Can a sole developer like myself really trust and &lt;em&gt;know&lt;/em&gt; that they aren’t doing something that I wouldn’t approve of?&lt;/p&gt;

&lt;p&gt;(Note that I’m not suggesting anything they may do is &lt;em&gt;bad&lt;/em&gt; just something I might not approve of, in this particular case.)&lt;/p&gt;

&lt;p&gt;This has honestly weighed on my mind since I released Issues.&lt;/p&gt;

&lt;h2 id=&quot;analytics&quot;&gt;Analytics&lt;/h2&gt;

&lt;p&gt;The reason I chose to include Google Analytics in the first place was a fear that I wouldn’t get some important data that would inform me about which decisions I should make.&lt;/p&gt;

&lt;p&gt;It turns out users have just emailed me about what they want. Almost every request has mentioned one omission, which was cut from previous versions because of time constraints and will make it into the upcoming version 1.2 of the app.&lt;/p&gt;

&lt;p&gt;I’ve already got a long list of features I would love to make and a vague order of their importance.&lt;/p&gt;

&lt;p&gt;The way I had Google Analytics showed no useful data. If I spent some time to research what to track it might help me, but just tracking pages revealed nothing but &lt;a href=&quot;http://www.startuplessonslearned.com/2009/12/why-vanity-metrics-are-dangerous.html&quot;&gt;vanity metrics&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At any rate, Issues isn’t an app I’m trying to encourage “engagement” in. The whole point is that you spend as little time as possible using it.&lt;/p&gt;

&lt;h2 id=&quot;crashes-from-itunes-connect--xcode&quot;&gt;Crashes from iTunes Connect &amp;amp; Xcode&lt;/h2&gt;

&lt;p&gt;Recently, I’ve had a couple of reports from beta testers of crashes and Xcode has picked them up. This was the point I realised that I really just didn’t need Crashlytics.&lt;/p&gt;

&lt;p&gt;It must be said that Crashlytics still has a superior way of viewing crashes than Xcode. For some reason Xcode wants you to select a version to fetch the crashes for that release of the app. When beta releases can be once every day or two, you end up with a lot of builds that &lt;em&gt;could&lt;/em&gt; contain crashes.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;/images/2015-11-16-removing-crashlytics/1.png&quot; alt=&quot;Many different builds in Xcode's build list&quot; width=&quot;144&quot; height=&quot;330&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Seriously, it’d be great if Xcode just had a list of crashes that you could then select and see what version it was, as it stands it’s quite easy to miss crashes. On the other hand, if a tester reports that build 2348 crashes then it’s easy to find. I’ve filled &lt;a href=&quot;rdar://23559628&quot;&gt;rdar://23559628&lt;/a&gt; (&lt;a href=&quot;http://openradar.appspot.com/23559628&quot;&gt;Open Radar&lt;/a&gt;) with Apple.&lt;/p&gt;

</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Finding explicit .png references in xibs</title>
   <link href="http://danieltull.co.uk/blog/2014/12/10/finding-explicit-png-references-in-xibs/"/>
   <updated>2014-12-10T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2014/12/10/finding-explicit-png-references-in-xibs</id>
   <content type="html">&lt;p&gt;I have come onto a project where I have been asked to move all images into asset libraries to more easily manage them. An issue is that the project’s many xib files reference the images as &lt;em&gt;image.png&lt;/em&gt; rather than just the image name &lt;em&gt;image&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I started to go through the ~20 xib files to remove the .png at the end of the image names. But after the first xib, I got bored. So I quickly came up with the following script, which finds all the .png references in all .xib files recursively inside the current directory.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grep -r -i --include=*.xib &quot;.png&quot; .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will list the files along with the line in the xib file it found, which can guide you as to where to look if it’s not obvious, as well as making sure you’ve converted all cases.&lt;/p&gt;

&lt;p&gt;However, I had a &lt;strong&gt;lot&lt;/strong&gt; of &lt;em&gt;.png&lt;/em&gt; references to change, and given that I had just automated finding them, surely I can automate the task of removing them?&lt;/p&gt;

&lt;p&gt;I found &lt;a href=&quot;http://www.praj.com.au/post/23691181208/grep-replace-text-string-in-files&quot;&gt;a solution&lt;/a&gt; which compromised of piping the result of my grep through &lt;code class=&quot;highlighter-rouge&quot;&gt;sort&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;uniq&lt;/code&gt;(ue) to a perl script which replaces the first instance of &lt;em&gt;.png&lt;/em&gt; that occurs on a line.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grep -r -i -l --include=*.xib &quot;.png&quot; . | sort | uniq | xargs perl -e &quot;s/.png//&quot; -pi&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Some xib entries had two images per line, but it was simple and quick enough to just run this script again to get the second occurance of the &lt;em&gt;.png&lt;/em&gt;.&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>An error was encountered while running</title>
   <link href="http://danieltull.co.uk/blog/2014/11/20/an-error-was-encountered-while-running/"/>
   <updated>2014-11-20T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2014/11/20/an-error-was-encountered-while-running</id>
   <content type="html">&lt;p&gt;Along with a lot of the rest of the iOS community, I was playing around with WatchKit yesterday, adding initial support to my app &lt;a href=&quot;https://itunes.apple.com/gb/app/coordination-location-utility/id625226776&quot;&gt;Coordination&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have previously implemented extensions and had an issue where the app fails to launch in the simulator and on the device, with the somewhat cryptic error message “An error was encountered while running (Domain = LaunchServicesError, Code = 0).”&lt;/p&gt;

&lt;p&gt;While I discovered the problem before, I just fixed it and carried on. This, it seems, was a mistake.&lt;/p&gt;

&lt;p&gt;The issue is that a framework had the same bundle identifier as the app and that is not allowed as &lt;a href=&quot;https://developer.apple.com/library/mac/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070&quot;&gt;each distinct app or bundle on the system must have a unique bundle ID&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the case yesterday I had logic that I wanted to use in the WatchKit app contained in my main application bundle. So I created a framework to put the shared logic into, which the iPhone and Watch apps would both link to and make use of.&lt;/p&gt;

&lt;p&gt;I added a shared framework target called “Coordination Framework” but wanted the product to just be called “Coordination” so that I could import it with &lt;code class=&quot;highlighter-rouge&quot;&gt;@import Coordination&lt;/code&gt;. This would contain the core logic for the app, but keep the view and interface controllers in their respective apps.&lt;/p&gt;

&lt;p&gt;By default the info.plist gives the bundle identifier as &lt;code class=&quot;highlighter-rouge&quot;&gt;uk.co.danieltull.$(PRODUCT_NAME:rfc1034identifier)&lt;/code&gt;, so because of my renaming the framework product, changed the identifier to &lt;code class=&quot;highlighter-rouge&quot;&gt;uk.co.danieltull.Coordination&lt;/code&gt; and you can guess what the bundle identifier of my app is!&lt;/p&gt;

&lt;p&gt;The solution I have is simple to add &lt;code class=&quot;highlighter-rouge&quot;&gt;-Framework&lt;/code&gt; to the end of the bundle identifier in my info.plist file.&lt;/p&gt;

&lt;p&gt;I have now &lt;a href=&quot;http://openradar.appspot.com/19045130&quot;&gt;filed a radar&lt;/a&gt; to suggest that Xcode should give an error if there are two bundles in the app with the same identifier, along with &lt;a href=&quot;https://github.com/danielctull-tests/Duplicate-Bundle-Identifier-Issue&quot;&gt;a test app demonstrating the issue&lt;/a&gt;.&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Notes on NSURLSession Task</title>
   <link href="http://danieltull.co.uk/blog/2014/08/04/notes-on-nsurlsession-task/"/>
   <updated>2014-08-04T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2014/08/04/notes-on-nsurlsession-task</id>
   <content type="html">&lt;p&gt;In an app I’m currently working on, I use NSURLSession download tasks to retrieve data from the network. I use the delegate methods so I can get notified of progress and fill in the details of an NSProgress object.&lt;/p&gt;

&lt;p&gt;The first thing to note is that while the following method appears to be about errors, it actually gets called on the completion of a task. If the task is successful, the error is nil. This actually went unnoticed far too long, leading to duplicate parsing of the data.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Another issue I’ve come across recently is that, due to the former bug, I wanted a single place to handle completion of the task. So, I ended up storing the location of the downloaded data from the following delegate method call and using it in the above method to retrieve the data.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This worked on iOS 7, where sometime &lt;em&gt;after&lt;/em&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;didCompleteWithError:&lt;/code&gt; the file would disappear.&lt;/p&gt;

&lt;p&gt;On iOS 8, the file clear up happens after &lt;code class=&quot;highlighter-rouge&quot;&gt;didFinishDownloadingToURL:&lt;/code&gt; and &lt;em&gt;before&lt;/em&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;didCompleteWithError:&lt;/code&gt; leading me to have completed requests with no error and no data.&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Retrofitting Asynchronous Unit Testing in Xcode 5</title>
   <link href="http://danieltull.co.uk/blog/2014/07/10/retrofitting-asynchronous-unit-testing-in-xcode-5/"/>
   <updated>2014-07-10T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2014/07/10/retrofitting-asynchronous-unit-testing-in-xcode-5</id>
   <content type="html">&lt;p&gt;With Xcode 6, Apple have finally given us a sanctioned way to perform asynchronous unit tests. For more information about this you can watch the WWDC 2014 session &lt;a href=&quot;https://developer.apple.com/videos/wwdc/2014/#414-video&quot;&gt;Testing in Xcode 6&lt;/a&gt; or read the new &lt;a href=&quot;https://developer.apple.com/library/prerelease/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_3_writing_test_classes/testing_3_writing_test_classes.html#//apple_ref/doc/uid/TP40014132-CH4-SW6&quot;&gt;Testing with Xcode&lt;/a&gt; document.&lt;/p&gt;

&lt;p&gt;Both of these show you how to adopt the new methods in Xcode 6, however some of us still need to build with Xcode 5.1 in the hope that we’ll ship before Xcode 6 is released, but may still want to test asynchronous methods now.&lt;/p&gt;

&lt;p&gt;Previously, I’ve used techniques similar to Mike Ash’s &lt;a href=&quot;https://www.mikeash.com/pyblog/friday-qa-2011-07-22-writing-unit-tests.html&quot;&gt;NSRunLoop-based example&lt;/a&gt; to cause the test to wait for my async code to finish running, which has worked well. Using this approach, I have recreated the basics of Apple’s asynchronous XCTest methods in a project called &lt;a href=&quot;https://github.com/danielctull/DCTAsynchronousTesting&quot;&gt;DCTAsynchronousTesting&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following shows how you would use this code, it might look extremely similar to examples from Apple’s documentation.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XCTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#import &amp;lt;AsynchronousTesting/AsynchronousTesting.h&amp;gt;
#import &quot;XCTestCase+DCTAsynchronousTesting.h&quot;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AsynchronousTestingTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;XCTestCase&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;@implementation&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AsynchronousTestingTests&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testExample&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;XCTestExpectation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expectation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;expectationWithDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSStringFromSelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AsynchronousTesting&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;performAsynchronousOperationWithCompletion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BOOL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;XCTAssertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;@&quot;Operation should have succeeded.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expectation&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fulfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}];&lt;/span&gt;

	&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;waitForExpectationsWithTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Hopefully this will help you write Xcode 6 compatible asynchronous tests until the “fall” comes.&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Easier merging of Xcode project files</title>
   <link href="http://danieltull.co.uk/blog/2013/09/05/easier-merging-of-xcode-project-files/"/>
   <updated>2013-09-05T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2013/09/05/easier-merging-of-xcode-project-files</id>
   <content type="html">&lt;p&gt;A while back, I discovered a script called &lt;a href=&quot;https://github.com/WebKit/webkit/blob/master/Tools/Scripts/sort-Xcode-project-file&quot;&gt;sort-Xcode-project-file&lt;/a&gt; in the WebKit project, which sorts the Xcode project by running the following command:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;perl sort-Xcode-project-file [Project].xcodeproj/project.pbxproj
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I started using it to make files easier to find in my projects and just nicer to look at. After a while, I discovered that it helps a lot with merging the Xcode project file. If both sides of the merge are sorted, there are fewer differences when merging, and makes almost all merges either automatic or extremely easy to tackle.&lt;/p&gt;

&lt;p&gt;This script has helped me manage project changes with multiple collaborators, so I suggest if you’re coming across merge issues with the Xcode project, or if you’ve got some amount of OCD, you try it out. I put the script in the repository, with a bash script to make it easier to run.&lt;/p&gt;

&lt;h2 id=&quot;words-of-warning&quot;&gt;Words of Warning&lt;/h2&gt;

&lt;p&gt;This script uses regex, so it’s potentially fragile and for this reason I &lt;em&gt;don’t&lt;/em&gt; run it as a pre-commit hook. I commit my changes and then run the script and commit the sorting changes separately, just in case it destroys my project.&lt;/p&gt;

&lt;p&gt;An annoying issue I’ve found is that when using static library sub-projects, I sometimes see a diff (as shown below) which swaps the order of a Products group containing the library’s targets. I’m not 100% sure why, I suppose that Xcode likes to sort them one way, but the script sorts another way.&lt;/p&gt;

&lt;p&gt;This diff can come up if you don’t run the script, which I assume is Xcode modifying it to its liking, and running the sort script will remove those changes.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@@ -1154,10 +1154,10 @@
                24D1F5C316BC464B001263D9 /* Products */ = {
                        isa = PBXGroup;
                        children = (
-                               24D1F5C916BC464B001263D9 /* libDCTAuth.a */,
-                               24D1F5CB16BC464B001263D9 /* DCTAuthTests.xctest */,
                                24D1F5CD16BC464B001263D9 /* DCTAuth.app */,
                                24DAF6D7177876D300D7B93F /* DCTAuth.bundle */,
+                               24D1F5CB16BC464B001263D9 /* DCTAuthTests.xctest */,
+                               24D1F5C916BC464B001263D9 /* libDCTAuth.a */,
                        );
                        name = Products;
                        sourceTree = &quot;&amp;lt;group&amp;gt;&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;What’s even weirder is that these groups don’t seem to be part of the main project file, but are contained in the library sub-projects. Those projects are untouched by the script, but I can’t seem to locate what else this section of the project XML might represent in the Xcode UI.&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Loading images in +load</title>
   <link href="http://danieltull.co.uk/blog/2013/05/14/loading-images-in-load/"/>
   <updated>2013-05-14T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2013/05/14/loading-images-in-load</id>
   <content type="html">&lt;p&gt;In my current app I have some UIButton subclasses which set up their own appearance, so that I can put these UIButton subclasses in a storyboard and have styled buttons.&lt;/p&gt;

&lt;p&gt;To do this I was putting my code in the +load method so that it would get loaded without me needing to call it from anywhere else, as shown below.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;@implementation&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DBSGreyButton&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttonImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;imageNamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;DBSGreyButton&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UIEdgeInsets&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;edgeInsets&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UIEdgeInsetsMake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buttonImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttonImage&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resizableImageWithCapInsets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;edgeInsets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appearance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;appearance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;appearance&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setBackgroundImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttonImage&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;forState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UIControlStateNormal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;appearance&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setTitleColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UIColor&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;darkTextColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                     &lt;span class=&quot;nf&quot;&gt;forState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UIControlStateNormal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Unfortunately, I discovered that the images that get loaded have the scale of 1. My solution is to have a +loadAppearance method that gets called from the AppDelegate.&lt;/p&gt;

&lt;p&gt;Thanks to Chris Parker for confirming that “&lt;a href=&quot;https://twitter.com/ctp/status/334215372611940352&amp;quot;&quot;&gt;+load fires before UIApplication init so scale isn’t set up yet…&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Edit: Thanks to Vadim Shpakovski for pointing out that +initialize does work for this, saying it’s “&lt;a href=&quot;https://twitter.com/vadimshpakovski/status/334229369876791296&amp;quot;&quot;&gt;One more reason to not use + (void)load and prefer + (void)initialize to reduce launch time in some cases.&lt;/a&gt;&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
 <entry>
   <title>Preventing Xcode 4 on Lion reopening windows</title>
   <link href="http://danieltull.co.uk/blog/2011/11/07/preventing-xcode-4-on-lion-reopening-windows/"/>
   <updated>2011-11-07T00:00:00+00:00</updated>
   <id>http://danieltull.co.uk/blog/2011/11/07/preventing-xcode-4-on-lion-reopening-windows</id>
   <content type="html">&lt;p&gt;Xcode 4 on Mac OS X Lion reopens all the projects from the last session. This is pretty frustrating to me most of the time as I switch from working on a client app or two plus a couple of my own. I’d rather be able to quit and reopen a fresh session to work on what I want at that moment, not have to sift through four or five spaces with different Xcode projects to find the one I want… every time I switch to and from another app.&lt;/p&gt;

&lt;p&gt;There used to be a way of preventing this in Xcode’s preference plist, but this no longer works. Instead, a solution is to set the following folder as locked, so Xcode can’t write to it to save the state.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~/Library/Saved\ Application\ State/com.apple.dt.Xcode.savedState
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You’ll want to delete the contents of this, then get info and click the locked checkbox. Et voila, no more projects reopening themselves.&lt;/p&gt;

&lt;p&gt;Thanks again to &lt;a href=&quot;http://twitter.com/dative&quot;&gt;Pete&lt;/a&gt; for letting me know about this. He should really be blogging these little facts!&lt;/p&gt;
</content>
   <author>
     <name>Daniel Tull</name>
     <uri>http://danieltull.co.uk/</uri>
   </author>
 </entry>
 
</feed>