<?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>Cocoa Is My Girlfriend</title>
	<atom:link href="http://www.cimgf.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.cimgf.com</link>
	<description>Taglines are for Windows programmers</description>
	<lastBuildDate>Thu, 10 May 2018 21:39:50 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.8.13</generator>
	<item>
		<title>Response: The Laws of Core Data</title>
		<link>https://www.cimgf.com/2018/05/10/response-the-laws-of-core-data/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Thu, 10 May 2018 21:39:50 +0000</pubDate>
				<category><![CDATA[Core Data]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2697</guid>

					<description><![CDATA[Recently, I saw a post from Dave DeLong and knowing his history with the framework I read it with extreme curiosity. Unfortunately, that read led to this post as I disagree strongly with a number of the laws he has laid down. Since I know people are going to be asking me about this post [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Recently, I saw a post from <a href="https://davedelong.com/blog/2018/05/09/the-laws-of-core-data">Dave DeLong</a> and knowing his history with the framework I read it with extreme curiosity.</p>
<p>Unfortunately, that read led to this post as I disagree <strong>strongly</strong> with a number of the laws he has laid down.</p>
<p>Since I know people are going to be asking me about this post (I am still getting asked about Simmons&#8217; post from a VERY long time ago), better to get my thoughts out now.</p>
<h2>1. Do not use Core Data as if it were a database</h2>
<p>No disagreement; Core Data is your object model and it <em>can</em> persist to a database but that is not its biggest strength.</p>
<h2>2. Do not use Core Data as if it were a SQLite wrapper</h2>
<p>This is re-iterating #1. Core Data is your object model, not a thin wrapper around a database.</p>
<h2>3. Your <code>NSManagedObjectContext</code> is your “stack”</h2>
<p>Here is where we start to disagree.  The <code>NSManagedObjectContext</code> is <em>not</em> your stack.  It is a scratchpad. It is where you stage changes to the data objects and decide to persist them or not.</p>
<p>I have advocated putting an object around it for convenience and Apple added the <code>NSPersistentContainer</code> which is designed to be subclassed. That wrapper is a great place to handle migrations, importing, exporting, convenience methods for accessing data; the list goes on.</p>
<p>All of the internal workings of your Core Data stack, your persistence and data model absolutely should be stored in the persistent container and that container should be injected through your controllers in your application.</p>
<h2>4. Never ever ever ever ever use an <code>NSManagedObject</code> outside its context’s queue</h2>
<p>No disagreement. Core Data is designed to work in a threaded environment but most of the objects are <strong>NOT</strong> designed to work on multiple threads/queues. As with ANY object, assume it is thread locked unless you can demonstrably confirm that it is safe to use across threads.</p>
<h2>5. Do not use <code>NSManagedObject</code> as if it were an <code>NSObject</code></h2>
<p>An <code>NSManagedObject</code> <strong>is</strong> an <code>NSObject</code> that has additional functionality added. It should absolutely be treated as if it is an <code>NSObject</code> because it is an <code>NSObject</code>. <code>NSManagedObject</code> instances are your data objects and should be treated as such. Creating Plain Old Objects on top of <code>NSManagedObject</code> instances is asking for pain and data corruption.</p>
<h2>6. You usually don’t need parent-child contexts</h2>
<p>If you are not accessing the network, exporting data, importing data or interacting with the outside world in any way, shape or form then this is correct.</p>
<p>If your app talks to <em>anything</em> else then you will want to use parent-child contexts.</p>
<p>The parent context should be on the user interface thread (the main thread) and when you need to do asynchronous work with your data objects (importing or exporting) then you want to do that on another thread and that work should be done in a child context.</p>
<p>A child context simplifies the transfer of notifications of data changes and greatly simplifies using Core Data in a multi-threaded environment.</p>
<h2>7. Keep your main queue context read-only</h2>
<p>The main queue is also known as the user interface queue.  The context that is associated with that queue should be for the user.  That context reads <strong>and writes</strong> data when the user is interacting with the application.</p>
<p>Should it be read-only?  Absolutely not.</p>
<p>Should it be user-only? Absolutely.</p>
<p>Any non-user work (importing and exporting) should be done on a child context on a background thread (see response to #6 above).</p>
<h2>8. Use an abstraction layer</h2>
<p>Please do not do this. You are going to make the next developer curse your name in a very unpleasant manner.</p>
<p>Use Core Data in your user interface.  Do not create dummy data objects on top of Core Data.  That leads to a maintenance nightmare.</p>
<p>Your user interface can use Core Data without really knowing that it is using Core Data.  Your user interface treats the <code>NSManagedObject</code> instances as if they were data objects because <strong>they are data objects</strong>.</p>
<p>Your user interface does not need to know any more about Core Data than it does for any other model structure.  Your user interface should talk to your persistent container subclass and ask for the data it needs.  The response to that request might be instances of <code>NSManagedObject</code> or might be an <code>NSFetchedResultsController</code> which then serves up the data objects in a consistent and reliable way.</p>
<h2>9. Use Core Data as a local cache</h2>
<p>I agree with the wording of this rule but I suspect the meaning is different.  Core Data, like any local persistence, is a local cache <em>of what is on the server</em>.  This is not specific to Core Data because that is what any local persistence does when you have data on a server.</p>
<p>Core Data is more than just a local cache.</p>
<h2>Core Data is not complicated</h2>
<p>Core Data is as complicated as you make it.  Most of the time you do not need or want the advanced features of Core Data and can just grab an instance of <code>NSPersistentContainer</code> and be happy.</p>
<p>When you need to deal with more complicated or interesting situations there is a fair chance that Core Data has an advanced feature to handle that situation.  For the 80%, you can ignore those advanced features and relax in the comfort knowing they are there for if/when you need them.</p>
<p>The harder your code is to write the harder it is going to be to maintain and debug.</p>
<p>Don&#8217;t make it harder on yourself. Keep it simple.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Developer Review: 2017 MacBook 12</title>
		<link>https://www.cimgf.com/2017/12/02/developer-review-2017-macbook-12/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Sat, 02 Dec 2017 06:51:12 +0000</pubDate>
				<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2666</guid>

					<description><![CDATA[After much consideration and review, I recently purchased a 2017 MacBook. No, not a MacBook Pro 13 or 15. I purchased the 12 inch MacBook. The small laptop that people say over and over again cannot be used for development. This is a living review of that MacBook as used by a macOS/iOS developer. How [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>After much consideration and review, I recently purchased a 2017 MacBook.</p>
<p>No, not a MacBook Pro 13 or 15. I purchased the 12 inch MacBook. The small laptop that people say over and over again cannot be used for development.</p>
<p>This is a living review of that MacBook as used by a macOS/iOS developer.<br />
<span id="more-2666"></span></p>
<h2>How I Work</h2>
<p>Whether I am coding or writing, I try and conserve motion as much as possible. My laptop is not doing 1000 different things at once. Nor am I continually compiling code or publishing my writing. Those actions are infrequent at best. Most of the time I am reading, studying, thinking and then, eventually, typing.</p>
<p>I sit and stare at the screen a lot.</p>
<p>Therefore, I am less concerned with the overall speed of the processor in my laptop than a gamer or video producer would be.</p>
<p>I do need memory though. Development tools are notoriously terrible about memory management and when you add in simulators, etc. to that mix, 4 or 8 GB of memory just isn&#8217;t sufficient.</p>
<p>I also need hard drive space. Projects get big with audio, video, and images fairly quickly. While I can make my projects fit onto the smallest drive, I would rather have breathing room if possible. I would rather NOT carry around external drives.</p>
<p>Therefore I settled on the MacBook with an I5 processor, 16GB of ram and a 512GB SSD drive.  Not the absolute top end machine but pretty close.</p>
<p>I would have selected the I3 with 16GB and a 512GB drive, but it was not an option that was available.</p>
<h2>Where I Work</h2>
<p>I like having a &#8220;rig&#8221; that can work anywhere. That means having a rig that can work in the worst situation.</p>
<p>For me, at 6&#8217;0&#8243; and broad-shouldered, a middle seat in coach on an international flight is probably the worst situation I will find myself in.</p>
<p>Therefore my rig needs to be able to work in a very small environment with no expectation of power.</p>
<p>I frequently will work from home, that being my home office or the couch.  My home office has an external monitor and lots of room for devices (my primary work is on mobile devices).</p>
<p>With that, I have an upper and lower requirement.</p>
<p>This is the smallest laptop in terms of footprint which means it will do well on a flight. I will report back on that one after my next flight.</p>
<p>USB-C, while not as great as Thunderbolt 3, is a very flexible port. With the docks that are available or even with Apple&#8217;s HDMI connector, I can set this machine up at my desk with a monitor, keyboard, trackpad and external drives. Those drives are limited to USB 3 speeds but that is plenty for development, back-ups, and repositories.</p>
<p>While I have not purchased a dock yet, I may in the near future and update.</p>
<p>With a monitor, Bluetooth trackpad and keyboard, this machine is a decent desktop unit. It drives an external display without issue.</p>
<h2>What&#8217;s in the Bag?</h2>
<p>My rig needs to be very transportable but fully usable in the field. The field might be a bus, a plane, a client&#8217;s office; sometimes even a racetrack. I am expected to ship code in all of those environments.</p>
<p>I want to keep the gear to a minimum. The less I bring, the less likely I am going to lose or forget something.</p>
<p>Current kit:</p>
<ul>
<li>MacBook 12</li>
<li>iPad Pro 9.7</li>
<li>Power for MacBook</li>
<li>HDMI Adapter for MacBook (also a USB-A Adapter)</li>
<li>USB-C to USB mini</li>
<li>USB-C to USB micro</li>
<li>USB-C to Lightning</li>
<li>USB-A to Lightning</li>
</ul>
<p>All of this fits easily into a proper waterproof bag that works well whether I am on a motorcycle or an airplane.</p>
<h2>Wireless Development</h2>
<p>This is the part where the current state of iOS development is awesome. The fact that I can develop against my phone, tablet and watch without a cable is a fantastic advancement; I absolutely love it.</p>
<p>I do carry sufficient cables with me just in case wireless stops working (happens occasionally) or if I am not on a wireless network that is strong enough to support it; most of the time I code without wires.</p>
<p>When you combine wireless development with the crazy battery life of the MacBook, I can easily get in a full day&#8217;s worth of work (more than 8 hours) without needing to plug in a thing.</p>
<h2>Battery Life</h2>
<p>I am a few weeks into using this machine and so far the battery life has been shocking.</p>
<p>I pretty much plug in the machine at the end of the day. It easily lasts me all day doing wireless development.  All day is more than 8 hours a day.</p>
<p>But read above. That includes a lot of staring at the screen, thinking, planning, walking away, etc. I am not hitting build every 2 seconds or intentionally trying to get it to burn its battery. Normal daily usage for me without caring whether I am on battery or not.</p>
<p>I intentionally plug it in when I am doing wired development and I suspect that wired development off the battery will have the laptop feeding power to the mobile device. I suspect I will find out on my next international flight.</p>
<p>The battery on this machine has really changed how I develop. Not watching the battery power through the day is surprisingly liberating.</p>
<h2>Speed of Development</h2>
<p>It is common for developers to look at pure clock speed when selecting a new laptop. In that department, the MacBook is definitely way behind the curve. If you look at just the numbers, you wonder if the MacBook can even run FaceBook in a browser or not.</p>
<p>In reality, the MacBook works extremely well. iOS, macOS, server and even Android development works just fine. Using both Xcode and Android Studio simultaneously offers no problem for the MacBook.</p>
<p>I suspect the upgrade to 16GB of ram really did the trick.</p>
<h2>Storyboards</h2>
<p>With the type of development that I am normally involved in, I do not work with storyboards often. Most of my work is at the persistence and networking layers, and therefore storyboards are rarely loaded on my machine.</p>
<p>However, storyboards do feel sluggish. Opening and working with a large storyboard is a test of patience but definitely doable. Given that storyboards are sluggish on my iMac as well, I am going to chock that up to storyboards/Xcode more than a deficiency in this particular laptop. If you are a heavy storyboard developer that item might give you pause. I suggest taking Xcode and a project on a drive to an Apple store and play. That one item could be a deciding factor for you.</p>
<h2>My Home Desk</h2>
<p>With this laptop, I work from literally anywhere in the house. This time of year I am spending a lot of time in the family room and the kitchen.</p>
<p>Needless to say, the laptop doesn&#8217;t get a lot of use while I am cooking, spending time with my family or gaming :)</p>
<p>But, I do have a home office as well.  My home desk is minimal as that is the way that I prefer to work.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2017/12/IMG_0084.jpg"><img src="https://www.cimgf.com/wp-content/uploads/2017/12/IMG_0084-1024x768.jpg" alt="Home Desk Image" width="256" align="right" class="aligncenter" hspace="10"/></a></p>
<p>The iPad is for documentation lookup, taking notes, drawing layouts, watching a movie while I work, etc. Sometimes it is my music player with my Groove external DAC! :)</p>
<p>The monitor is a simple Samsung 1080p HDMI which connects to the Apple HDMI adapter. I <em>might</em> upgrade it next year to a 4K.</p>
<p>I have a powered 7 port USB 3 hub also connected to the Apple adapter which allows me to connect as many devices as I need while at my home desk.</p>
<p>I have a small USB-C extension cable that connects to a left side port to the laptop and lets me store the <em>OMG Dongle</em> behind the monitor to reduce the clutter on my desk.</p>
<p>This configuration gives me a ton of screen to work with and I certainly do not feel constrained.</p>
<h2>OMG Dongles!!!</h2>
<p>This argument crops up every few years, and it is just repeating drama.</p>
<p>When the floppy drive was dropped; people lost their minds.</p>
<p>When the serial port was dropped; people lost their minds.</p>
<p>When the optical drive was dropped; people lost their minds.</p>
<p>When ADP was dropped&#8230;</p>
<p>When DVI was dropped&#8230;</p>
<p>There are more I am forgetting.  Same drama, over and over again.</p>
<p>Look at the list above: I carry exactly <b>ONE</b> dongle with me.</p>
<p>I upgraded a few cables, switched out USB-A cables with USB-C cables so that I can connect to external drives and devices.  Total cost was less than $50.00 (not including the dongle).</p>
<p>My external drives still work.</p>
<p>I can access every device that I could access before.</p>
<p>A few years from now people will be making jokes about how people used to carry so many different cables.</p>
<p>Connectors change; life goes on.</p>
<h2>Worth It?</h2>
<p>Being able to carry a full rig that is light enough that I forget I am carrying it is fantastic.</p>
<p>So far there are no regrets about the purchase and no hindrance to development. If anything, I am getting more done now because I am able to take this laptop with me everywhere without it being a burden.</p>
<p>Would I rebuild an OS on it?  Not if I can help it.</p>
<p>But as a highly portable machine, it does great for development.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Modern Network Operation</title>
		<link>https://www.cimgf.com/2016/01/28/a-modern-network-operation/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Thu, 28 Jan 2016 20:12:28 +0000</pubDate>
				<category><![CDATA[NSOperation]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2648</guid>

					<description><![CDATA[When Apple introduced the NSURLSession API, the landscape of network operations changed. In some ways, the new API made things worse as the block API that was added tempts developers to become very sloppy with network calls. The block API makes it trivial to add network calls anywhere in an application. Very little thought or [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>When Apple introduced the <code>NSURLSession</code> API, the landscape of network operations changed. In some ways, the new API made things worse as the block API that was added tempts developers to become very sloppy with network calls.  The block API makes it trivial to add network calls anywhere in an application.  Very little thought or structure is required.  From this (and some third party libraries who followed the same pattern) we have seen an explosion of increasingly poor network handling in applications.</p>
<p>For my own purposes I have resisted this slippery slope as often as possible. However I still preferred the way <code>NSURLConnection</code> worked and how it integrated nicely with <code>NSOperation</code> subclasses.  My attempts at using the <code>NSURLSession</code> were cumbersome and didn’t feel “right”.</p>
<p>Fortunately, I have recently worked on a design that I have been quite pleased with.  In this design I am happily using <code>NSOperation</code> subclasses again and I am using the <code>NSURLSession</code> API.<br />
<span id="more-2648"></span></p>
<h2>Changes to <code>NSOperaton</code> implementation</h2>
<p>One of the reasons that it took me so long to discover this pattern was due to forgetting about a way to implement <code>NSOperation</code> subclasses and taking control of the life-cycle of the <code>NSOperation</code>. This was not a feature I used very often and therefore did not think about using it with the <code>NSURLSession</code> API.</p>
<p>After various experiments and research I re-discovered this option and the following update to my network operation design was born.</p>
<p>The most complicated change (and probably a change that someone will suggest a better solution to) has to do with the <code>finished</code> property on the <code>NSOperation</code>. This property is defined as <code>readonly</code> which is a bit more enforced in Swift than it was in Objective-C.  In Objective-C it was a simple matter of creating a setter accessor and manipulating the underlying <code>ivar</code> that the property generates.  However, in Swift, I have not found a way to do that exactly the same.  Therefore I ended up overriding the property completely:</p>
<pre><code>var junk: Bool = false
override var finished: Bool {
    get {
        return junk
    }
    set (newAnswer) {
        willChangeValueForKey("isFinished")
        junk = newAnswer
        didChangeValueForKey("isFinished")
    }
}
</code></pre>
<p>Note that I am triggering a KVO notification on <code>isFinished</code> as opposed to <code>finished</code> which is what the property name is. This seems to be a Swift-ism as the <code>NSOperation</code> get accessor is called <code>isFinished</code> instead of <code>getFinished</code> and I suspect that is part of why I need to tickle the accessor name instead of the property name.</p>
<p>Since I am building a base class to extend my actual network operations from, there are a couple of other variables that I added:</p>
<pre><code>let incomingData = NSMutableData()
var sessionTask: NSURLSessionTask?
var localURLSession: NSURLSession {
    return NSURLSession(configuration: localConfig, delegate: self, delegateQueue: nil)
}
var localConfig: NSURLSessionConfiguration {
    return NSURLSessionConfiguration.defaultSessionConfiguration()
}
</code></pre>
<p>The <code>incomingData</code> property will hold the data coming back from the network operation.  This property can be used in a few ways.</p>
<p>The <code>sessionTask</code> will hold a reference to the task that will be created so that we have access to it even when it is not responding back to its delegate.  Speaking of delegates, this subclass of <code>NSOperation</code> also implements the <code>NSURLSessionDataDelegate</code> as is hinted at in the <code>localURLSession</code> property.</p>
<p>Both the <code>localURLSession</code> property and the <code>localConfig</code> property can be overridden by a subclass.  This is intentional as using a non-default configuration or session is usual for me but I want to leave the option open.</p>
<h3>start()</h3>
<p>With these variables made available, the start function is fairly straight-forward.</p>
<pre><code>override func start() {
    if cancelled {
        finished = true
        return
    }

    guard let url = NSURL(string: “aURL”) else { fatalError("Failed to build URL") }

    let request = NSMutableURLRequest(URL: url)

    sessionTask = localURLSession.dataTaskWithRequest(request)
    sessionTask!.resume()
}
</code></pre>
<p>Because I am now completely in control of the life-cycle of this <code>NSOperation</code> it is prudent to check <code>isCancelled</code> immediately upon entry into this function.  It is entirely possible that the operation has been flagged as cancelled before it began.  Therefore I will immediately set the <code>finished</code> flag to <code>true</code> if the operation has been cancelled.</p>
<p>I could have built the <code>url</code> property without the guard and just unwrapped it but I prefer the guard syntax for that so that when I do have a problem I get a human readable error message.  Personal preference.</p>
<p>The <code>start()</code> function merely kicks off the task and completes.</p>
<p>Because we have overridden the <code>start()</code> function and specifically not called <code>super.start()</code> the <code>NSOperation</code> will continue to reside in the queue, “running”, as far as the <code>NSOperationQueue</code> is concerned until I set the <code>finished</code> property to <code>true</code>.</p>
<p>From here I needed to implement a minimum of three functions to complete the delegate implementation.</p>
<h3>didReceiveResponse:</h3>
<pre><code>func URLSession(session: NSURLSession, 
    dataTask: NSURLSessionDataTask, 
    didReceiveResponse response: NSURLResponse, 
    completionHandler: (NSURLSessionResponseDisposition) -&gt; Void) {
    if cancelled {
        finished = true
        sessionTask?.cancel()
        return
    }
    //Check the response code and react appropriately
    completionHandler(.Allow)
}
</code></pre>
<p>This is another opportunity to watch for the cancellation of the operation and to abort if the flag has been set to <code>true</code>. If it hasn’t then the next step (left as only a comment for brevity) is to check the status of the response and make a decision how to proceed.</p>
<p>The normal procedure here is to execute the <code>completionHandler</code> and pass it the value of <code>.Allow</code> to tell the <code>NSURLSession</code> to continue with the task.</p>
<h3>didReceiveData:</h3>
<pre><code>func URLSession(session: NSURLSession, 
    dataTask: NSURLSessionDataTask, 
    didReceiveData data: NSData) {
    if cancelled {
        finished = true
        sessionTask?.cancel()
        return
    }
    incomingData.appendData(data)
}
</code></pre>
<p>This delegate method is expected to be called numerous times during the life-cycle of this <code>NSOperation</code>.  Each time it is called it adds a bit more data to what has been received.  Once we have confirmed that the operation has not been cancelled, the next step is to add the packet that was received to the <code>incomingData</code> property.</p>
<h3>didCompleteWithError:</h3>
<pre><code>func URLSession(session: NSURLSession, 
    task: NSURLSessionTask, 
    didCompleteWithError error: NSError?) {
    if cancelled {
        finished = true
        sessionTask?.cancel()
        return
    }
    if NSThread.isMainThread() { log("Main Thread!") }
    if error != nil {
        log("Failed to receive response: \(error)")
        finished = true
        return
    }
    processData()
    finished = true
}
</code></pre>
<p>This is the final of the delegate methods we need to implement.  There are others that we <em>can</em> implement if we need to deal with authentication or redirects.</p>
<p>In this function, after confirming that it is not cancelled, we need to check to see if there was an error.  If there is an error we effectively abort the operation, throw away the data and change the <code>finished</code> flag.  Depending on your application and your expectations, you may want to fire a <code>NSNotification</code> or handle some other kind of behavior to notify the application that the network operation failed.</p>
<p>When the operation doesn’t fail I then call <code>processData()</code> which does nothing in the base class.  The expectation is that the subclass of this base class will implement the <code>processData()</code> function and handle its specific processing of that data.</p>
<h2>Wrap Up</h2>
<p>With this implementation I am able to build network operations that are small discrete units of work that I can easily test with a unit test.  I can expand upon this by passing in a <code>NSManagedObjectContext</code> and have my <code>processData()</code> function create a private child of that passed in context and consume the data received from the server.</p>
<p>I can also attach a completion block to the NSOperation and get bandwidth information from the operation if I want and make adjustments to the assumptions of the application based on the current bandwidth.</p>
<p>By using <code>NSOperation</code> subclasses I can now prioritize my network calls (posting to twitter is a higher priority than receiving avatars from twitter for example), cancel operations that are no longer needed (avatars or images that are no longer on screen) and in general be a much better citizen by only keeping the radios on for as long as I need them and not any longer.</p>
<p>Further, I can now watch for application life-cycle events in my <code>NetworkController</code> and terminate operations when my application goes into the background, further improving my citizenship status.  I can also look for operations that <strong>need</strong> to finish when the application goes into the background and request additional background time.</p>
<p>I hope that you find this article helpful and if you have any questions about this design, please feel free to contact me at <code>marcus@cimgf.com</code>.</p>
<p><a href="mailto:marcus@cimgf.com"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2011/08/Signoff-300x88.png" alt="Signoff" width="300" height="88" class="alignright size-medium wp-image-1481" srcset="https://www.cimgf.com/wp-content/uploads/2011/08/Signoff-300x88.png 300w, https://www.cimgf.com/wp-content/uploads/2011/08/Signoff.png 453w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Swift Type Constrained Extensions: Express Yourself</title>
		<link>https://www.cimgf.com/2015/12/14/swift-type-constrained-extensions-express-yourself/</link>
					<comments>https://www.cimgf.com/2015/12/14/swift-type-constrained-extensions-express-yourself/#comments</comments>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Mon, 14 Dec 2015 18:19:55 +0000</pubDate>
				<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Playgrounds]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2565</guid>

					<description><![CDATA[I admit it. I was pretty down when Swift was announced. I appreciated the finer points of the reasons for it, however, they weren&#8217;t convincing&#8211;at least not to me&#8211;not at first. I denied that it was actually &#8220;expressive&#8221; as the overall community was referring to it, however, that was before version 2. It&#8217;s at the [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I admit it. I was pretty down when Swift was announced. I appreciated the finer points of the reasons for it, however, they weren&#8217;t convincing&#8211;at least not to me&#8211;not at first. I denied that it was actually &#8220;expressive&#8221; as the overall community was referring to it, however, that was before version 2. It&#8217;s at the point when the lights went on for me. I am now a convert and this post explains why&#8211;at least one of the reasons. The only question I ask now is while you can do some really cool expressive things, should you? You&#8217;ll see what I mean if you read on.<br />
<span id="more-2565"></span></p>
<p><strong>tl;dr;</strong></p>
<p>You can download the <a href="https://github.com/perlmunger/MovieLister" target="_blank">code and playground</a> for this post from github.</p>
<h2>What Are Type Constrained Extensions</h2>
<p>One of Swift&#8217;s most expressive and powerful features is type constrained extensions. If you&#8217;re new to Swift coming from Objective-C, think of it as a category in Objective-C yet with the ability to specify type criteria so that your category (extension) only applies to the class <em>if</em> it conforms to a certain type. For example, if you have an array of your own custom objects, you can create functions that are specific to an array of your objects. Here&#8217;s a quick snippet similar to one that I <a href="https://twitter.com/perlmunger/status/647080996232269825">posted to Twitter</a> a while back:</p>
<pre lang="swift">
class Thing {
    var name:String
    init(name:String) {
        self.name = name
    }
}

extension Array where Element : Thing {
    func whereNamed(name:String) -> [Element] {
        return self.filter( { $0.name == name } )
    }
}

let thing1 = Thing(name: "Thing 1")
let thing2 = Thing(name: "Thing 2")
let thing3 = Thing(name: "Thing 3")

let things = [thing1, thing2, thing3]

let found = things.whereNamed("Thing 2")
</pre>
<p>After the code runs in a playground the <code>found</code> variable contains an array of <code>Thing</code>s with the name &#8220;Thing 2&#8221;. Obviously, you could just run filter on the <code>Thing</code>s array and achieve the same result, but the code demonstrates the capability succinctly. This is a very cool feature of the Swift language. You can create any function you want that is specific to arrays of your <code>Thing</code> objects.</p>
<p>Yes, you can, in essence, do the same in Objective-C using a category on <code>NSArray</code>, but there is no type safety. It would look something like this:</p>
<pre lang="objc">
@interface NSArray (Additions)
- (NSArray*)whereNamed:(NSString*)name;
@end

@implementation NSArray (Additions)

- (NSArray*)whereNamed:(NSString*)name
{
    return [self filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name = %@", name]];
}
@end
</pre>
<p>You can call <code>whereNamed:</code> on any <code>NSArray</code> and it will work fine as long as the object inside your array has a property named <code>name</code>.</p>
<h2>Adding App Specific Functionality</h2>
<p>Let&#8217;s talk about type constrained extensions by way of an example. If you&#8217;ve written code for mobile apps for any significant amount of time, the one thing you can do in your sleep is fetch JSON from a URL, parse it, and display it in your UI. Recently while prototyping I decided that instead of creating an object hierarchy I would just use the arrays of dictionaries as parsed by the <code>NSJSONSerialization</code> class. But then I got to thinking about it and realized that if I use type constraints, I can add some properties to my dictionaries that are specific to the data in the JSON feed. Here&#8217;s what I mean.</p>
<p>Let&#8217;s start with downloading JSON from iTunes. If you go to this URL: <a href="https://itunes.apple.com/us/rss/topmovies/limit=50/json">https://itunes.apple.com/us/rss/topmovies/limit=50/json</a> it will download the JSON for the top 50 movies currently in the store. The output currently looks like this in a browser (well, assuming you have a JSON parser plugin).</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2015/12/itunesjson.png" rel="attachment wp-att-2577"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2015/12/itunesjson.png" alt="iTunes JSON" class="alignleft size-thumbnail wp-image-2577" width="300" height="300" /></a>.</p>
<p>So given this url, let&#8217;s download it (in a view controller just for discussion purposes).</p>
<pre lang="swift">
let url = NSURL(string: "https://itunes.apple.com/us/rss/topmovies/limit=50/json")

var movies = [[String:AnyObject]]()

override func viewDidLoad() {
    super.viewDidLoad()

    self.downloadData()
}

func downloadData() {
    
    let task = NSURLSession.sharedSession().dataTaskWithURL(self.url!) { [weak self] (data, response, error) -> Void in
        do {
            if let records = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject] {
                self?.movies = records.movieEntries
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self?.tableView.reloadData()
                })
            }
        } catch {
            
        }
    }
    
    task.resume()
}
</pre>
<p>In this code you can see we&#8217;ve created an array-of-dictionaries, <code>String</code> to <code>AnyObject</code>, variable called <code>movies</code> to hold our downloaded/parsed data and then we have a function to perform the download from our iTunes URL. The download gets spun off in the background using an <code>NSURLSession</code> in <code>viewDidLoad</code>. When the download completes, using an <code>NSURLSessionDataTask</code>, the data is now in memory and we can parse it using the <code>NSJSONSerialization</code> class. After parsing completes, we set our <code>movies</code> class variable to the parsed result and then we reload the table view causing it to display the data. Now look closely, though. See how the <code>records</code> variable is type casted as an optional <code>[String:AnyObject]</code> dictionary, yet it has a property on it called <code>moveEntries</code>. Where did that come from? How does a dictionary know anything about <code>movieEntries</code>? Take a look at this extension.</p>
<pre lang="swift">
extension Dictionary where Key : StringLiteralConvertible, Value : AnyObject {
    var movieEntries : [[String:AnyObject]] {
        if let feed = self["feed"] as? [String:AnyObject] {
            return feed["entry"] as! [[String:AnyObject]]
        }
        return []
    }
}
</pre>
<p>This extension is constrained to a <code>String</code> (well, StringLiteralConverrible technically) key and an <code>AnyObject</code> value which matches the type of our dictionary. Once you&#8217;ve implemented this extension even code completion now knows about it and will happily suggest <code>movieEntries</code> to you when you type a dot after you type <code>records</code> in the download task completion handler.</p>
<h2>You Can, But Should You?</h2>
<p>I alluded to this notion earlier, but what I have just demonstrated is really cool and interesting, but you should think about whether it is something you should do in a shipping app. A number of thoughts come to mind. Say, for example, that you grab an object embedded deeper in your JSON/dictionary hierarchy. You would need to create some properties specific to that object as well and the intention of your code may lose clarity. The <code>movieEntries</code> property I demonstrated grabs the &#8220;feed&#8221; dictionary, and then grabs the &#8220;entry&#8221; array of dictionaries (refer to <a href="https://itunes.apple.com/us/rss/topmovies/limit=50/json">the feed JSON</a> again if this is unclear). The &#8220;entry&#8221; array contains the movie entries themselves in an array. So, say you want to grab a property of a specific movie entry. Now your extension looks like this for the <code>movieName</code> property.</p>
<pre lang="swift">
extension Dictionary where Key : StringLiteralConvertible, Value : AnyObject {
    var movieName : String {
        if let nameObj = self["im:name"] as? [String:AnyObject] {
            return nameObj["label"] as! String
        }
        return ""
    }
    
    var movieEntries : [[String:AnyObject]] {
        if let feed = self["feed"] as? [String:AnyObject] {
            return feed["entry"] as! [[String:AnyObject]]
        }
        return []
    }
}
</pre>
<p>Now, presumably, you&#8217;ll know by the context of the code when you want to access a property and when you don&#8217;t, however, as I mentioned, this reduces the code clarity making it more difficult to understand what&#8217;s going on. Read this code in a couple months after not having touched it in a while and you&#8217;ll see what I mean. While writing obscure code might be (arguably) great for your job security, it&#8217;s not a best practice. However, you have to admit that this capability is really cool! I really love the expressiveness it demonstrates.</p>
<p>So in spite of my warnings, let&#8217;s keep going. When my extension was finished, it looked like this:</p>
<pre lang="swift">
extension Dictionary where Key : StringLiteralConvertible, Value : AnyObject {
    
    var movieName : String {
        if let nameObj = self["im:name"] as? [String:AnyObject] {
            return nameObj["label"] as! String
        }
        return ""
    }

    var movieSummary : String {
        if let summary = self["summary"] as? [String:AnyObject] {
            return summary["label"] as! String
        }
        return ""
    }
    
    var movieThumnailURL : NSURL? {
        if let imageItems = self["im:image"] as? [[String:AnyObject]] {
            let firstOne = imageItems[0]["label"] as! String
            return NSURL(string: firstOne)
        }
        return nil
    }
    
    var movieEntries : [[String:AnyObject]] {
        if let feed = self["feed"] as? [String:AnyObject] {
            return feed["entry"] as! [[String:AnyObject]]
        }
        return []
    }
}
</pre>
<p>I access the the movie object specific properties in my <code>cellForRowAtIndexPath:</code> in this next snippet. Notice I&#8217;ve grabbed the image URL to download the movie thumbnail (The download code is quick and dirty in the view controller. Don&#8217;t do this in a real shipping app).</p>
<pre lang="swift">
var images = [NSIndexPath:UIImage]()

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    let object = self.movies[indexPath.row]           // Grab a movie object from our parsed array
    
    cell.textLabel!.text = object.movieName           // Movie name property
    cell.detailTextLabel!.text = object.movieSummary  // Movie summary property

    
    if let image = self.images[indexPath] {          // Use the cached image if it exists
        cell.imageView?.image = image
    } else {                                         // Otherwise download it
        if let url = object.movieThumnailURL {       // Movie thumbnail URL property
            let task = NSURLSession.sharedSession().dataTaskWithURL(url) { [weak self] (data, response, error) -> Void in
                if let data = data {
                    if let image = UIImage(data: data) {
                        self?.images[indexPath] = image  // Cache the image so it doesn't get re-requested
                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
                            self?.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
                        })
                    }
                    
                }
            }
            task.resume()           
        }
    }
    
    return cell
}
</pre>
<p>(The download and caching code here is immaterial to the goals of this post except to point out that I grabbed the URL using the same typed constrained dictionary. How you implement an image cache will likely vary depending on your app&#8217;s requirements.)</p>
<h2>Primitives Need Not Apply, Well Sorta</h2>
<p>At this point you&#8217;ve probably already thought of some cool ways you could leverage this capability (if not, you will), but as with everything else there are limitations that require you to think about your problem before attempting to solve it. Let me provide an example. When working with paths, <code>CGPathRef</code> or <code>UIBezierPath</code>, you don&#8217;t typically want to initialize your paths and pass them around, but instead you&#8217;ll keep around an array of <code>CGPoint</code>s and only convert the points to a path when you&#8217;re ready to render it. Wouldn&#8217;t it be cool if an array of <code>CGPoint</code>s had a calculated property called <code>path</code> that would return the <code>CGPathRef</code> you need to render it? Enter type constrained extensions.</p>
<pre lang="swift">
extension Array where Element : CGPoint {
    var path : CGPathRef {
        let bezier = UIBezierPath()

        if self.count > 0 {
            bezier.moveToPoint(point)
        }

        for i in 1..< self.count {
            let point = self[i]
            bezier.addLineToPoint(point.point)
        }

        return bezier.CGPath
    }
}
</pre>
<p>(This is a simplistic example and likely wouldn't suit every need for building out a path, however, the point is again about the convenience that type constrained extensions provide)</p>
<p>And voila! Your array of elements now has a variable called <code>path</code>.</p>
<pre lang="swift">
var points = [CGPoint]()
// .. add some points
let path = points.path
</pre>
<p><strong>Except it doesn't work!</strong> Sorry. I know. You were all excited. Well fear not. We will make this work, but first you have to realize that type constraining is looking for objects. <code>CGPoint</code> is a primitive (struct). I know what you're thinking. Let's just wrap a <code>CGPoint</code> in a class and away we go. Well, you could do. How about this instead, though? Let's create a protocol that <code>CGPoint</code> can conform to and constrain it to that instead.</p>
<pre lang="swift">
protocol Pointable {
    var point : CGPoint { get }
}

extension CGPoint : Pointable {
    var point : CGPoint {
        return self
    }
}
</pre>
<p>So now our type constrained array looks like this:</p>
<pre lang="swift">
extension Array where Element : Pointable {
    var path : CGPathRef {
        let bezier = UIBezierPath()

        if self.count > 0 {
            bezier.moveToPoint(self[0].point)
        }

        for i in 1..< self.count {
            let point = self[i]
            bezier.addLineToPoint(point.point)
        }

        return bezier.CGPath
    }
}
</pre>
<p>Now, with a minor addition of a protocol and making <code>CGPoint</code> conform to it, our <code>path</code> variable on the array of <code>Pointable</code>s works as expected.</p>
<h2>Conclusion</h2>
<p>I will conclude with one more practical example. If you've ever needed to manage the items in your navigation bar, you've probably wondered if there is a simpler way to do so other than managing the items array. Well, there really isn't, however, by using a type constrained array extension, you can add functionality that makes managing the items more intuitive. Here's what I mean. For an app I'm working on, I needed to remove one of the nav bar items in a form view controller when I loaded data for editing, but needed it to be available when creating a new object from the form data. Here's what I did:</p>
<pre lang="swift">
extension Array where Element : UIBarButtonItem {
    mutating func removeItemWithTitle(title:String) {
        for item in self {
            if item.title == title {
                self.removeObject(item)
            }
        }
    }
}
</pre>
<p>Notice my function is marked with the <code>mutating</code> keyword to indicate that the function can make changes to the internal array. So now when I load my view controller, I just check to see if my object instance variable is non-nil indicating that we're editing and just remove the navigation item like this if we are:</p>
<pre lang="swift">
self.navigationItem.rightBarButtonItems?.removeItemWithTitle("Search")
</pre>
<p>It's pretty powerful to be able to work this way. I'm finding this functionality to come in handy in a lot of situations. As I said at the beginning, I wasn't exactly enamored with Swift when I first started using it, but the improvements and features we've seen get added to the language in the more recent versions make it a language that is interesting, fun, and expressive to use. You can can call me a believer. I'm really starting to love using Swift. Until next time.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cimgf.com/2015/12/14/swift-type-constrained-extensions-express-yourself/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Massive View Controllers</title>
		<link>https://www.cimgf.com/2015/09/21/massive-view-controllers/</link>
					<comments>https://www.cimgf.com/2015/09/21/massive-view-controllers/#comments</comments>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Mon, 21 Sep 2015 19:58:15 +0000</pubDate>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[KVO/KVC]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2552</guid>

					<description><![CDATA[While at Empirical Development and then MartianCraft I had been distanced from all of the inventive solutions that other development teams have been coming up with for the past few years. I was living in a bubble of our development teams. Now that I am working independently again, I am being exposed to a large [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>While at Empirical Development and then MartianCraft I had been distanced from all of the inventive solutions that other development teams have been coming up with for the past few years.  I was living in a bubble of our development teams.</p>
<p>Now that I am working independently again, I am being exposed to a large number of interesting code bases.</p>
<p>It came as quite a surprise to me that view controllers are considered bad by many developers and that they have been coming up with some rather <em>intersting</em> solutions to make them more &#8220;manageable&#8221;.</p>
<p>To me, this is an indication that many developers have lost the perspective on what should and what should not be in a view controller.  For some reason there is a misconception going around that <strong>everything</strong> belongs in the view controller.</p>
<p>Madness!</p>
<p>Lets break it down.<br />
<span id="more-2552"></span></p>
<h2>Network Code</h2>
<p>I have spoken about this at length at conferences around the world.</p>
<p>Putting network code in the view controller is beyond a code smell, it is just wrong.</p>
<p>Where does it go?</p>
<p>All of the network code belongs in <code>NSOperation</code> subclasses.  Ideally one <code>NSOperation</code> subclass for each network request.  That <code>NSOperation</code> is responsible for creating the network request, receiving the data, parsing it into JSON and storing it in the persistence layer (ideally Core Data).</p>
<p>This creates small, discrete, units of work that are easy to maintain.  If a network operation fails, we can isolate the code and find the problem.  Further, we can put each call into a unit test very easily and run it in isolation until it is perfect.</p>
<p>But where do we fire these operatons from?  I <em>strongly</em> recommend creating a top level data controller that is responsible for maintaining a reference to the persistence engine (again, ideally Core Data).  This top level data controller is normally instantiated in the application&#8217;s delegate and is passed down to the view controllers via dependency injection.</p>
<p>Using a singleton for this is bad; another code smell.  Why is a subject for another discussion.</p>
<p>What does this look like?</p>
<p>The data controller starts out very simply:</p>
<pre><code>import UIKit
import CoreData

class DataController: NSObject {
    var managedObjectContext: NSManagedObjectContext
    let networkQueue = NSOperationQueue()

    init(completionClosure: () -&gt; ()) {
        //initialize persistence.  NOT LAZY
    }

    func refreshRequest() {
    let op = OperationSubclass()
    op.dataController = self
    op.url = ... //Pass in what is needed
    self.networkQueue.addOperation(op)
    }
}
</code></pre>
<p>With this class being passed into the view controller the view controller can react to refresh requests by simply calling:</p>
<pre><code>self.dataController.refreshRequest()    
</code></pre>
<p>One line of code that can be wired directly from the button&#8217;s action directly to the data controller.</p>
<p>Consolidating the networking code into a central location also adds additional benefits beyond just code isolation.  Real time reaction to bandwidth changes, resumability, cancellability, and many other features become trivial to implement.  When the network code is in the view controllers the same features are nearly impossible to implement.</p>
<p>How does the view know when the data is ready?</p>
<p>There are a few answers depending on on what kind of view we are dealing with.</p>
<h2>The UITableViewController</h2>
<p>This is the easiest type of view controller to work with.  When we are using Core Data as our persistence engine the view controller practically writes itself.</p>
<p>By putting a NSFetchedResultsController between the data controller and the table view controller, we have extremely brief method implementations.</p>
<p>But what about the table view cells?</p>
<p>Each table view cell should be designed in the storyboard and then populated via a <code>UITableViewCell</code> subclass.  No fuss no muss.</p>
<p>With this <strong>simple</strong> design the population from the view controller can be as easy as:</p>
<pre><code>override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as! CustomTableViewCell
    let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject

    cell.populateCellFromObject(object)
    return cell
}
</code></pre>
<p>Let the view subclass handle populating the labels, images, whatever else is needed to draw the cell.</p>
<p>By keeping the network code out of the view controller and letting the views draw themselves, the view controller becomes very simple.  All it really ends up doing is managing the life cycle of the view, exactly what the view controller is meant to do.</p>
<p>Why add more complexity?</p>
<h2>Plain View Controllers</h2>
<p>Plain view controllers can be a little harder, but generally do not need to be.</p>
<p>The previous view controller is usually responsible for injecting the needed data objects into the view controller.  If you aren&#8217;t using dependency injection here you are probably doing it wrong.</p>
<p>With the data being injected the view controller just needs to pass that data to the view subclass.</p>
<p>Let the view populate itself from the data!</p>
<p>Let the view controller manage life cycle events.</p>
<p>Build the view in the storyboard.</p>
<p>Use either KVO or core data change notifications to refresh the view.  The view controller <strong>does not</strong> need to handle the data refresh if the data objects do not change.</p>
<p>Use Dependency Injection.  The UIKit framework was designed for it.  When you avoid it you are fighting the frameworks and just making everything harder on yourself.</p>
<h2>Duplicating data</h2>
<p>A few of the interesting design patterns that I have seen recently involve duplicating the data in memory.  Sometimes there are two copies of the data, one in the cache (aka persistence layer) and another for the views.</p>
<p>This defeats some of the most amazing pieces of Cocoa!</p>
<p>When our UI has a single copy of a data object we can observe changes on that data object.</p>
<p>We can use KVO (Key Value Observing) or we can use notifications from Core Data to detect changes to the data to react and refresh.</p>
<p>Why is this important?</p>
<p>We do not need to write code to watch the cache!</p>
<p>Our network layer simply updates the cache and the view will update itself.  We completely avoid tight coupling between the network layer and the view layer.</p>
<p>Our code base gets smaller.</p>
<p>Our code base gets more maintainable.</p>
<p>Our code base gets faster.</p>
<p>When we duplicate the data and/or try to introduce other design patterns into UIKit based applications we are adding unnecessary complexity.</p>
<h2>Why subclass the view?</h2>
<p>The <code>UIView</code> class is meant to be subclassed.  The documentation on this class is well defined and subclasses of <code>UIView</code> integrate extremely well into the UIKit framework.</p>
<p>When the <code>UIView</code> is subclassed and the data is injected into the view, the view can be reused.  This is the core of the concept of code reuse.  If a piece of data is going to be displayed in multiple places then it makes sense that there should be a view to be reused.</p>
<h2>What about data validation?</h2>
<p>When we subclass the view and the view is aware of the data, guess where the data validation goes?</p>
<p><strong>In the view subclass!</strong></p>
<p>Why?  So that the view can <em>respond</em> to the validation failures!</p>
<p>This is a big difference between OS X and iOS.  In OS X, Cocoa Bindings allow the view elements to query the data directly and confirm validation.  This is a very cool feature that makes validation borderline magic.</p>
<p>But Cocoa Bindings do not exist on iOS.  Therefore we <strong>must</strong> validate the data as close to the editing view as possible.  This allows us a very short path back to the user to notify the user that the data is invalid.</p>
<p>What better place than in the view itself?</p>
<p>If we do this at the persistence layer, it is too late.  At best it will cause a tight coupling between the persistence layer and the view layer.  A very bad thing. At worst the user will be in a bad state.  Unable to save their data and forced to go find the edit view again that is probably off screen, deallocated, gone.  A terrible user experience.</p>
<p>When we design our user inteface to have data validation feedback it then becomes trivial to validate the data upon entry and give the user immediate feedback.</p>
<h2>What about business logic?</h2>
<p>What is business logic?</p>
<p>Business logic is code that is not part of putting data on the screen and is not part of receiving data from the network (generally).</p>
<p>If the business logic is about posting something to a server, then it belongs in the network layer!</p>
<p>If the business logic is about controlling a device, then it belongs in a manager for that device.</p>
<p>Define what your business logic is and then determine where it goes.  Very rarely does it belong in the view controller.</p>
<h2>Doesn&#8217;t this make the views heavy?</h2>
<p>No.</p>
<p>The code to populate the view must live somewhere.  If we put it in the view controller then the view controller gets too big.</p>
<p>If we create an object to sit between the view and the view controller then we are creating unnecessary additional objects.</p>
<p>The view is already holding onto references to the elements contained in the view that are provided from the storyboard, it makes perfect sense to put the population code with the references to what is being populated.</p>
<p>This does not make our code any heavier than any other design.  The code is arguably a class lighter per view.</p>
<h2>What is left over</h2>
<p>When we remove the view population and the data code from the view controller; the view controller is trimmed down dramatically.  Now the view controller is back down to doing its job, view lifecycle events.</p>
<p>Even the view lifecycle events have been dramatically reduced over the past few years with the introduction of storyboards.</p>
<h2>Wrap up</h2>
<p>We must never forget the <a href="https://en.wikipedia.org/wiki/KISS_principle">K.I.S.S. principal</a>.  It absolutely applies to iOS and OS X development.  When we introduce multiple layers of indirection, multiple copies of the data, we are adding completely unnecessary complexity to the application.</p>
<p>That complexity will cost us.  It will cost us CPU, Battery Life, Memory, and maintainability.</p>
<p>Why do it the hard way?</p>
<h2>About the Author</h2>
<p>Marcus S. Zarra is best known for his expertise with Core Data, persistence and networking.  He has been developing Cocoa applications since 2004 and has been developing software for most of his life.<a href="https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k.jpg"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k-300x200.jpg" alt="Teaching at CocoaConf" width="300" height="200" class="size-medium wp-image-2545" align="right" srcset="https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k-300x200.jpg 300w, https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k-1024x683.jpg 1024w, https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k.jpg 2048w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>There are very few developers who have worked in more environments, on more projects or with more teams than Marcus has.</p>
<p>Marcus is currently available for short to medium term development contracts, code reviews and workshops.</p>
<p>If your team is struggling with code structure, networking, or persistence please contact him.  He would love to help your team produce the best application possible.</p>
<p>Marcus can be reached via email at <a href="mailto:marcus@cimgf.com">marcus@cimgf.com</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cimgf.com/2015/09/21/massive-view-controllers/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>The Next Chapter</title>
		<link>https://www.cimgf.com/2015/08/04/the-next-chapter/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Tue, 04 Aug 2015 15:05:54 +0000</pubDate>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Core Data]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2543</guid>

					<description><![CDATA[As of August 1, 2015 I am no longer part of MartianCraft. It is time to move on to the next chapter. What is Next? Long term I have some ideas that will take a bit of time to put into place. In the short time I am eager to help as many teams as [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k.jpg"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k-300x200.jpg" alt="Speaking at CocoaConf" width="300" height="200" align="right" class="alignright size-medium wp-image-2545" srcset="https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k-300x200.jpg 300w, https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k-1024x683.jpg 1024w, https://www.cimgf.com/wp-content/uploads/2015/08/16527445294_f4109d3405_k.jpg 2048w" sizes="(max-width: 300px) 100vw, 300px" /></a>As of August 1, 2015 I am no longer part of MartianCraft.</p>
<p>It is time to move on to the next chapter.</p>
<h2>What is Next?</h2>
<p>Long term I have some ideas that will take a bit of time to put into place.  In the short time I am eager to help as many teams as possible through short term contracting, consulting and workshops.  I really do enjoy helping teams get the most out of their persistence and networking layers.</p>
<p>Therefore&#8230;</p>
<p>Effective immediately, I am available for short term and possibly long term contract work.</p>
<p>While I can assist with any form of iOS or OS X development, my area of expertise is in networking and persistence; specifically Core Data.</p>
<p>If you are not familiar with my experience, here are a few highlights:</p>
<ul>
<li>Wrote &#8220;The Book&#8221; on <a href="https://pragprog.com/book/mzcd2/core-data">Core Data</a>.</li>
<li>Taught at universities around the United States</li>
<li>Spoken at nearly every Apple related tech conference around the world</li>
<li>Provided workshops on persistence, Core Data and Networking at many conferences and large corporations in and around the United States.</li>
<li>Developed some of the most complex applications ever conceived for the iOS platform</li>
</ul>
<h2>What are the options?</h2>
<p>I am looking for short term projects unless it is truly amazing, cutting edge, and never done before.  I am looking to help <strong>your</strong> team provide a better experience for <strong>your</strong> users.</p>
<p>We can accomplish this either through a monthly, weekly, daily contract or through a workshop. The details of which we can discuss in detail. I am available to travel and can work on site for short periods of time.</p>
<p>Are you struggling with your persistence or networking layer?</p>
<p>Are you having performance issues that you are unable to isolate?</p>
<p>Would you like a fresh set of eyes on your project to get an idea of where things are?</p>
<p><a href="mailto:marcus@cimgf.com">Contact me</a>; we can discuss the options.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Core Data and Aggregate Fetches In Swift</title>
		<link>https://www.cimgf.com/2015/06/25/core-data-and-aggregate-fetches-in-swift/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Thu, 25 Jun 2015 16:47:07 +0000</pubDate>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2482</guid>

					<description><![CDATA[You can find other articles on the interwebs about NSExpression and NSExpressionDescription, however, I wasn&#8217;t really satisfied with the explanations I&#8217;ve seen. I decided to write a post myself after I recently had to become much more intimate with the way Core Data aggregate fetches work. I hope this will make clear what has to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>You can find other articles on the interwebs about <code>NSExpression</code> and <code>NSExpressionDescription</code>, however, I wasn&#8217;t really satisfied with the explanations I&#8217;ve seen. I decided to write a post myself after I recently had to become much more intimate with the way Core Data aggregate fetches work. I hope this will make clear what has to be done in order to harness this powerful feature of Core Data.</p>
<p>You&#8217;ve heard it said before and sometimes in a scolding tone, &#8220;CORE DATA IS NOT A DATABASE. IT&#8217;S AN OBJECT GRAPH!&#8221;. What normally follows is a discussion about what that means, if you&#8217;re lucky. Otherwise, you&#8217;re just on your own to go figure it out. In my mind, though, it&#8217;s not necessarily wrong to think of it as a database as they have enough things in common to make it a reasonable thing to do and at the end of the day Core Data is backed by a SQLite database. I think that if it helps you understand what is going on behind the scenes better, then go for it. You do have to remember some key differences that can bite you like the need to fetch before updating or deleting, for example. Though with recent additions&#8211;last year with iOS 8&#8217;s <a href="https://developer.apple.com/library/ios/releasenotes/General/iOS80APIDiffs/frameworks/CoreData.html">NSBatchUpdateRequest</a> (link to iOS 8 API diff since it&#8217;s not currently documented) which allows you to perform a batch update similar to a SQL update query or this year with iOS 9&#8217;s <code>NSBatchDeleteRequest</code> (<a href="https://developer.apple.com/videos/wwdc/2015/?id=220">See WWDC 2015 session 220 for more info</a>) which allows for batch deletes based on whatever predicate you give it, the lines seem to be blurring more and more.<span id="more-2482"></span></p>
<blockquote><p><strong>tl;dr;</strong> Get the source code here: <a href="https://github.com/perlmunger/Aggregate">Core Data and Aggregate Fetches Code on Github</a>. <strong>The project and source were created with Xcode 7 beta and Swift 2.0 but they&#8217;ve now been updated to Xcode 8 and Swift 3.</strong></p></blockquote>
<p>When it comes to aggregating data, or in more simple database-y terms, data you want to group by, it&#8217;s not immediately obvious in Core Data how to go about what you need using a fetch&#8211;to the point where some have wondered if it was even possible. It would be nice if there were some mechanism or even syntactic sugar around it that would make it a little more database-y since that makes it easier to grasp, but I think that if we start from a database SQL query and work our way back to a Core Data fetch that uses <code>NSExpression</code> and <code>NSExpressionDescription</code>, it will make a whole lot more sense. Let&#8217;s get started by considering some data:</p>
<p><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2015/06/AcmeHatCoDataTable.png" alt="" width="700" height="363" class="alignleft size-full wp-image-2536" srcset="https://www.cimgf.com/wp-content/uploads/2015/06/AcmeHatCoDataTable.png 700w, https://www.cimgf.com/wp-content/uploads/2015/06/AcmeHatCoDataTable-300x156.png 300w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<p>I&#8217;ve seen this kind of data many times. It&#8217;s a report that you might get from a company who wants to display sales reports for reps or customers. You can see that this data is flattened. It&#8217;s not normalized. Instead of using multiple tables you have a single table that has a way to represent a parent entity. In the case of the data above, this is represented by the column called &#8220;ProductLine&#8221;. In SQL, if we wanted to get a report of the total sum of all of the items grouped by product line, it would go something like this:</p>
<pre lang="sql">
SELECT ProductLine, SUM(Sold) as SoldCount FROM Products GROUP BY ProductLine
</pre>
<p>And the results would looks something like this:</p>
<pre>
ProductLine  SoldCount 
-----------  ----------
Bowler       48        
Stetson      142       
Top Hat      50  
</pre>
<p>So the question is, how do we translate this query into a Core Data fetch?</p>
<h2>The Basics of Aggregate Fetching</h2>
<p>The concept behind the SQL query is simple and easy to understand, but until you see how each component part of the query translates to a Core Data <code>NSExpression</code> or <code>NSExpressionDescription</code> it can be a little confusing getting the results you want in Core Data. Here are a few basic points that will clarify things a little as we head into writing our Core Data query code.</p>
<ul>
<li><strong>When you fetch the records, you are going to be requesting that Core Data returns you an array of dictionaries</strong>. This makes sense if you think about it. You won&#8217;t get back a list of managed objects because the data doesn&#8217;t represent a single record and therefore entity. Instead, it represents rows in your data model that have been manipulated to provide an aggregate dataset&#8211;a sum of all rows grouped by product line in our case.</li>
<p></p>
<li><strong>Just as in the SQL query, you need a name for your aggregate &#8220;column&#8221;</strong>. When you run the query directly in SQLite, you don&#8217;t have to use the &#8220;as&#8221; keyword and provide a label&#8211;it will provide one for you. However, in your Core Data Query, you&#8217;re going to need to name your aggregate column.</li>
<p></p>
<li><strong>Just as in the SQL query, you need to list the columns you want to group by</strong>. This will be the same column names you listed in your select minus the aggregate columns.</li>
<p>
</ul>
<p>Our final aggregate query that we&#8217;re going to build is going to also include a sum of the returned counts. It looks like this:</p>
<pre lang="sql">
SELECT ProductLine, SUM(Sold) as SoldCount, SUM(Returned) as ReturnedCount FROM Products GROUP BY ProductLine
</pre>
<p>And the output of this query using the SQLite CLI looks like this:</p>
<pre>
ProductLine  SoldCount   ReturnedCount
-----------  ----------  -------------
Bowler       48          4            
Stetson      142         27           
Top Hat      50          6  
</pre>
<h2>Fetching Some Aggregate Data</h2>
<p>When a fetch request is handed to your managed object context to fetch your data it needs to have a list of columns you want to use for your fetch specified by a list of either <code>NSExpressionDescription</code> objects or <code>String</code>s. Here&#8217;s how to determine which one you should use. Look again at our query:</p>
<pre lang="sql">
SELECT ProductLine, SUM(Sold) as SoldCount, SUM(Returned) as ReturnedCount FROM Products GROUP BY ProductLine
</pre>
<p>We have three items we want returned. &#8220;ProductLine&#8221; is an actual column in our table&#8211;for that we should use a <code>String</code>, while SoldCount and ReturnedCount are new columns we are creating for our query result. They need to be added as <code>NSExpressionDescription</code> objects.</p>
<blockquote><p><strong>NOTE: </strong>The data we&#8217;ve been using in the discussion up until now is contrived other than having been placed into a Numbers spreadsheet and, from there (as CSV), imported into a SQLite database just to run the command line queries&#8211;the results of which you&#8217;ve seen above. Here, however, we depart from that data and will reference similar fields, but ones that we are actually using in the demo project. The differences are subtle, &#8220;ProductLine&#8221; vs &#8220;productLine&#8221;, etc. however, it seems important to mention since the following will seem inconsistent unless we explain. Carry on.</p></blockquote>
<p>If you look at the signature for the property <code>propertiesToFetch</code> on <code>NSFetchRequest</code> you see it takes an array of <code>Any</code>:</p>
<pre lang="swift">
@available(iOS 3.0, *)
open var propertiesToFetch: [Any]?
</pre>
<p>So when your fetch request is ready to execute, you just give it an array containing <code>String</code>s and <code>NSExpressionDescriptions</code>. Here is how I begin my code to build up these expressions.</p>
<pre lang="swift">
var expressionDescriptions = [AnyObject]()
expressionDescriptions.append("productLine" as AnyObject)
</pre>
<p>As a first step I go ahead and append the <code>String</code>s I need as you can see above. Next, I go ahead and build up the expression description objects. Let&#8217;s take the first one, SoldCount, and see how it is setup in code:</p>
<pre lang="swift">
// Create an expression description for our SoldCount column
var expressionDescription = NSExpressionDescription()
// Name the column
expressionDescription.name = "SoldCount"
// Use an expression to specify what aggregate action we want to take and
// on which column. In this case sum on the sold column
expressionDescription.expression = NSExpression(format: "@sum.sold")
// Specify the return type we expect
expressionDescription.expressionResultType = .integer32AttributeType
</pre>
<p>Now that it this one is built out, add it to our AnyObject array:</p>
<pre lang="swift">
// Append the description to our array
expressionDescriptions.append(expressionDescription)
</pre>
<p>Now let&#8217;s do the same for our ReturnedCount column:</p>
<pre lang="swift">
// Create an expression description for our ReturnedCount column
expressionDescription = NSExpressionDescription()
// Name the column
expressionDescription.name = "ReturnedCount"
// Use an expression to specify what aggregate action we want to take and
// on which column. In this case sum on the returned column
expressionDescription.expression = NSExpression(format: "@sum.returned")
// Specify the return type we expect
expressionDescription.expressionResultType = .integer32AttributeType
</pre>
<p>And add it to the array as well:</p>
<pre lang="swift">
// Append the description to our array
expressionDescriptions.append(expressionDescription)
</pre>
<p>All that&#8217;s left now is to build up our fetch request.</p>
<h2>Put It All Together</h2>
<p>When we create our fetch request the two fields that are most pertinent are the <code>propertiesToGroupBy</code>, and <code>propertiesToFetch</code>. In the <code>propertiesToGroupBy</code> we provide an array containing just the one field, &#8220;productLine&#8221;. In the <code>propertiesToFetch</code> we specify our AnyObject array that contains <code>String</code>s and <code>NSExpressionDescription</code> objects. Here is the code to build up the fetch request.</p>
<pre lang="swift">
// Build out our fetch request the usual way
let request = NSFetchRequest<NSFetchRequestResult>(entityName: self.entityName)
// This is the column we are grouping by. Notice this is the only non aggregate column.
request.propertiesToGroupBy = ["productLine"]
// Specify we want dictionaries to be returned
request.resultType = .dictionaryResultType
// Hand off our expression descriptions to the propertiesToFetch field. Expressed as strings
// these are ["productLine", "SoldCount", "ReturnedCount"] where productLine is the value
// we are grouping by.
request.propertiesToFetch = expressionDescriptions
</pre>
<p>You can set other fields on the fetch request as usual, like adding an array of <code>NSSortDescriptors</code>, for example:</p>
<pre lang="swift">
// Go ahead and specify a sorter
request.sortDescriptors = [NSSortDescriptor(key: "productLine", ascending: true)]
</pre>
<p>Finally, here is what the code looks like altogether as a class function on our <code>NSManagedObject</code> subclass:</p>
<pre lang="swift">
class func aggregateProductsInContext(context:NSManagedObjectContext) -> [[String:AnyObject]]? {

    // Create an array of AnyObject since it needs to contain multiple types--strings and
    // NSExpressionDescriptions
    var expressionDescriptions = [AnyObject]()
    
    // We want productLine to be one of the columns returned, so just add it as a string
    expressionDescriptions.append("productLine" as AnyObject)
    
    // Create an expression description for our SoldCount column
    var expressionDescription = NSExpressionDescription()
    // Name the column
    expressionDescription.name = "SoldCount"
    // Use an expression to specify what aggregate action we want to take and
    // on which column. In this case sum on the sold column
    expressionDescription.expression = NSExpression(format: "@sum.sold")
    // Specify the return type we expect
    expressionDescription.expressionResultType = .integer32AttributeType
    // Append the description to our array
    expressionDescriptions.append(expressionDescription)
    
    // Create an expression description for our ReturnedCount column
    expressionDescription = NSExpressionDescription()
    // Name the column
    expressionDescription.name = "ReturnedCount"
    // Use an expression to specify what aggregate action we want to take and
    // on which column. In this case sum on the returned column
    expressionDescription.expression = NSExpression(format: "@sum.returned")
    // Specify the return type we expect
    expressionDescription.expressionResultType = .integer32AttributeType
    // Append the description to our array
    expressionDescriptions.append(expressionDescription)
    
    // Build out our fetch request the usual way
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: self.entityName)
    // This is the column we are grouping by. Notice this is the only non aggregate column.
    request.propertiesToGroupBy = ["productLine"]
    // Specify we want dictionaries to be returned
    request.resultType = .dictionaryResultType
    // Go ahead and specify a sorter
    request.sortDescriptors = [NSSortDescriptor(key: "productLine", ascending: true)]
    // Hand off our expression descriptions to the propertiesToFetch field. Expressed as strings
    // these are ["productLine", "SoldCount", "ReturnedCount"] where productLine is the value
    // we are grouping by.
    request.propertiesToFetch = expressionDescriptions
    
    // Our result is going to be an array of dictionaries.
    var results:[[String:AnyObject]]?
    
    // Perform the fetch. This is using Swfit 2, so we need a do/try/catch
    do {
        results = try context.fetch(request) as? [[String:AnyObject]]
    } catch _ {
        // If it fails, ensure the array is nil
        results = nil
    }
    
    return results
}
</pre>
<p>When this function returns, we get a nice tidy little array of dictionaries that looks something like this:</p>
<pre>
[
    ["SoldCount": 48, "productLine": Bowler, "ReturnedCount": 4], 
    ["SoldCount": 142, "productLine": Stetson, "ReturnedCount": 27], 
    ["SoldCount": 50, "productLine": Top Hat, "ReturnedCount": 6]
]
</pre>
<p>Which is exactly what we want. We can then just use this array directly as our data for our <code>UITableView</code> data source on the master side of our split view controller. Here is what our app looks like with the data fully populated (click to enlarge):</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2015/06/acmehatcoscreenshot.png"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2015/06/acmehatcoscreenshot-300x225.png" alt="acmehatcoscreenshot" width="300" height="225" class="alignleft size-medium wp-image-2528" srcset="https://www.cimgf.com/wp-content/uploads/2015/06/acmehatcoscreenshot-300x225.png 300w, https://www.cimgf.com/wp-content/uploads/2015/06/acmehatcoscreenshot.png 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>You can see that we&#8217;ve built out the detail side of the split view controller to also display a table view that contains a list of all of the products for the selected product line. Take a look at the <a href="https://github.com/perlmunger/Aggregate">source project on GitHub</a> and build the source yourself to see how it all comes together. This post and the source code for it have now been updated to Swift 3 and Xcode 8.</p>
<h2>Conclusion</h2>
<p>For me the impetus of mastering the aggregate fetch was poor performance doing it another way. Yes, you can achieve the results you want by performing aggregate functions on arrays of data manually, but I noticed in places where I was doing this in an app I work on the performance was growing steadily worse the more data the customer added to the table in question. Experience with RDBMSs (in some other lifetime) reminded me that performing the right query could be far more efficient and so the search was on to find an appropriate optimization. In the mean time I had resorted to doing a background fetch (on a background context) and calculation that loaded an activity spinner to let the user know that the fetch/calculation was occurring, but I hated doing that to my users&#8211;and I guarantee they hated that experience. Once I found a way to properly do an aggregate fetch (as demonstrated in this post), I didn&#8217;t even have to perform it in the background. What was taking up to 30 seconds before, was now taking milliseconds. That is a nice optimization that makes for happier users. Until next time.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xcode Continuous Integration: &#8220;Server encountered an error with Apple Developer&#8221;</title>
		<link>https://www.cimgf.com/2015/04/01/xcode-continuous-integration-server-encountered-an-error-with-apple-developer/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Wed, 01 Apr 2015 15:44:58 +0000</pubDate>
				<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2445</guid>

					<description><![CDATA[If you get this message when you are adding your server to a team to implement continuous integration using Xcode bots and OS X server: Server encountered an error with Apple Developer. Please try again later. If the problem persists, contact Apple Developer Technical Support for help. It could be a red herring. There&#8217;s a [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>If you get this message when you are adding your server to a team to implement continuous integration using Xcode bots and OS X server:</p>
<blockquote><p>
Server encountered an error with Apple Developer.</p>
<p>Please try again later. If the problem persists, contact Apple Developer Technical Support for help.
</p></blockquote>
<p>It could be a red herring. There&#8217;s a support note here: <a href="https://support.apple.com/en-us/HT203853">https://support.apple.com/en-us/HT203853</a> that states the issue has to do with making sure you login as an Agent or Admin. That&#8217;s probably a valid scenario, but it may not be as in my case. I got this error message simply because an updated program license agreement needed to be accepted on the web portal. Once that was done, I was able to add the server to the team and could continue on.</p>
<p>(Yes, I know it&#8217;s April first, but this is not a joke)</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>MCE Conf 2015</title>
		<link>https://www.cimgf.com/2015/02/13/mce-conf-2015/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Fri, 13 Feb 2015 20:27:46 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2436</guid>

					<description><![CDATA[Late last year I was contacted by the organizers of MCE Conf and was asked to speak. Since it fit within my schedule (which can be its own challenge these days) I accepted without thinking too much about it. Shortly after my acceptance I had heard that there was some controversy surrounding the conference about [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Late last year I was contacted by the organizers of MCE Conf and was asked to speak.  Since it fit within my schedule (which can be its own challenge these days) I accepted without thinking too much about it.</p>
<p>Shortly after my acceptance I had heard that there was some controversy surrounding the conference about a comment made by one of the organizers who had attended another conference.  After reading up on the controversy I figured; &#8220;oh well, how bad can it be?&#8221;</p>
<p>The short answer? It was amazing.  I absolutely loved every minute of the conference.<br />
<span id="more-2436"></span></p>
<h2>The Venue</h2>
<p>The conference proper was held at the Palace of Culture and Science in the center of Warsaw. The first floor of the palace has been converted into a movie theater.  What this meant to me as a speaker is that I would be speaking to an audience in an amphitheater environment.</p>
<p>A little known secret.</p>
<p>A lot of speakers are introverts. Introverts <em>spend</em> energy to be in a group or crowd.  When you are on stage you can feed off the audience’s energy to give a better performance.  You feed off that energy by seeing the faces of the audience and their reactions to your talk.</p>
<p>In an amphitheater the speaker feeds off the entire audience, not just the front row or two.</p>
<p>The energy in the talks was amazing.  It was almost palpable.  After watching some of the talks on the first day I was excited to do my talk.  I couldn’t wait to be the focus of that energy.</p>
<h2>The people</h2>
<p>I always learn a tremendous amount about other cultures when I travel outside of the USA to give a talk.  When I arrive at a new venue the first thing I do is walk the city and just explore.  Take in the vibe of the city and of the culture that I am being exposed to.</p>
<p>It is amazing what you can learn just walking around, visiting the shops, looking at the restaurants, etc.  It is a fantastic way to learn about a place you have never been to before.</p>
<p>At the conference, the vibe was great.  People were excited to be there.  I was not recognized very much at this conference which worked to my benefit.  I got to walk around, engage in conversations and just listen.  Listen to the other speakers, listen to the attendees.  Listen to the conversations instead of being the center of the conversation.  I really learned a lot about how others go about being a developer or designer.</p>
<p>There were an incredible number of cultures represented at this conference.  I dare say, more cultures than any other conference I have been to.  I can’t say why it seemed so diverse but it was just a wealth of knowledge and experience to learn from.</p>
<h2>My Talk</h2>
<p>First talk of the year.</p>
<p>Completely new venue.</p>
<p>A technical talk without a single line of code.</p>
<p>What is there to be nervous about?</p>
<p>I approached the stage both excited and nervous.  I have learned how to deal with the normal “I am on stage” nervousness (ask me over a drink sometime how I did that), this was another level.  Everything could go wrong.</p>
<p>My talk already went through a last minute change just before I went on stage so I was past that.</p>
<p>I already rearranged how the stage worked so I got past that.</p>
<p>But still, new audience, new material.</p>
<p>For me; the talk was fantastic.  The audience was incredible.  From my first slide I felt the harmony and energy.  As I clicked to the second slide I knew this talk was going to be great.</p>
<p>Others can judge the content of my talk.</p>
<p>Others can judge my presentation.</p>
<p>The audience and venue were so incredible that I was disappointed when I ran out of time.  I wanted to feel that energy forever.  I could have stayed up there forever.</p>
<p>It is the high I feel when I am racing motorcycles.</p>
<p>It is a high that no drug can give you.</p>
<p>As soon as it is over you want it again.</p>
<h2>See you again soon</h2>
<p>I hope to have another opportunity to speak at MCE.  It was a fantastic experience for me.</p>
<p>And the controversy?  As with most drama; completely overblown nonsense.  A cultural mistranslation at best.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>We&#8217;ll Miss You Jordan</title>
		<link>https://www.cimgf.com/2015/01/12/well-miss-you-jordan/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Tue, 13 Jan 2015 00:35:46 +0000</pubDate>
				<category><![CDATA[Fuck Cancer]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2422</guid>

					<description><![CDATA[Until today we had no category for a post like this. It now exists&#8230; We offer our deepest condolences, thoughts, and prayers for all those affected by the tragic loss of such a great friend to this community, Jordan Breeding. He lost his fight with cancer this morning and we grieve deeply along with the [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Until today we had no category for a post like this. It now exists&#8230;</p>
<p>We offer our deepest condolences, thoughts, and prayers for all those affected by the tragic loss of such a great friend to this community, Jordan Breeding. He lost his fight with cancer this morning and we grieve deeply along with the rest of you. Jordan will be sorely missed.</p>
<p>Sincerely and with heavy hearts,</p>
<ul>
<li>Marcus, Matt, and the rest of the CIMGF family.</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Beginning iOS Development With Swift</title>
		<link>https://www.cimgf.com/2014/12/02/beginning-ios-development-with-swift/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Tue, 02 Dec 2014 19:35:06 +0000</pubDate>
				<category><![CDATA[Beginner]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2416</guid>

					<description><![CDATA[Many years ago now, I wrote a tutorial for the beginner to learn how to use outlets and actions as this is often one of the least familiar aspects for new developers who are wanting to learn iOS. It&#8217;s simple once you&#8217;ve seen it, but until then, there&#8217;s a gap. This time around I&#8217;m presenting [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Many years ago now, <a href="https://www.cimgf.com/2008/10/01/cocoa-touch-tutorial-iphone-application-example/" title="Cocoa Touch Tutorial ca. 2008" target="_blank">I wrote a tutorial</a> for the beginner to learn how to use outlets and actions as this is often one of the least familiar aspects for new developers who are wanting to learn iOS. It&#8217;s simple once you&#8217;ve seen it, but until then, there&#8217;s a gap. This time around I&#8217;m presenting an application that is similar to the one I did back then, however, it&#8217;s up to date with Xcode 6 and Swift. If you are new to iOS development, this should help get you going.</p>
<p><iframe loading="lazy" src="//player.vimeo.com/video/113170420" width="500" height="313" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p>
<p><a href="http://vimeo.com/113170420">Beginning iOS Application Development with Swift</a> from <a href="http://vimeo.com/user2563726">Skye Road Systems</a> on <a href="https://vimeo.com">Vimeo</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Swift and valueForKeyPath: You Can&#8217;t Keep A Good API Down!</title>
		<link>https://www.cimgf.com/2014/11/05/swift-and-valueforkeypath-you-cant-keep-a-good-api-down/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Wed, 05 Nov 2014 19:43:51 +0000</pubDate>
				<category><![CDATA[Playgrounds]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2389</guid>

					<description><![CDATA[tl;dr; Download the Value For Key Path Playground I was incredibly disappointed in Swift when I started to look into how key value coding might be preserved in the transition from Objective-C. Of course, Apple would preserve that, right? And I don&#8217;t mean by resorting to using Foundation classes&#8211;you know all type-casty and everything (yeah, [&#8230;]]]></description>
										<content:encoded><![CDATA[<hr/>
<p><strong>tl;dr;</strong> Download the <a href="https://www.cimgf.com/wp-content/uploads/2014/11/VFKPlayground.playground1.zip">Value For Key Path Playground</a></p>
<hr/>
<p>I was incredibly disappointed in Swift when I started to look into how key value coding might be preserved in the transition from Objective-C. Of course, Apple would preserve that, right? And I don&#8217;t mean by resorting to using Foundation classes&#8211;you know all type-casty and everything (yeah, type-casty). Are we progressing forward or looking to the past, after all? I shouldn&#8217;t have to rely on NSArray like this:</p>
<pre lang="swift">
var values = (items as NSArray).valueForKeyPath("value")
</pre>
<p>Right? Who wants to do that? What&#8217;s the proper Swift way?</p>
<p>Well, my early assumption from what I was seeing in Swift was that valueForKeyPath: was gone and no longer did we have a convenient way to grab only the fields we needed from a collection of objects. It appeared that it couldn&#8217;t be done&#8211;at least not in any idiomatic elegant way. Then I downloaded some sample code from the Apple developer site and noticed they were doing what I needed, but using map to do it. The answer was map. Here&#8217;s an example:</p>
<pre lang="swift">
var lastNames = items.map({$0["last"]! as String})
</pre>
<p>Now the lastNames variable contains a list of strings with just the last name property of my items array. Given an array of dictionaries like this, you can see how that is providing pretty much what we used to get from valueForKeyPath:</p>
<pre lang="swift">
var items = [
    ["first" : "Billy", "last" : "Bogart", "address" : ["street" : "111 Main Street"]],
    ["first" : "Gary", "last" : "Gollum", "address" : ["street" : "2277 AB Street"]],
    ["first" : "David", "last" : "Dangerly", "address" : ["street" : "22311 Place Ave."]],
    ["first" : "Johnny", "last" : "Jones", "address" : ["street" : "10 Orange Rd."]]
]
</pre>
<p>lastNames now contains:</p>
<pre lang="swift">
["Bogart", "Gollum", "Dangerly", "Jones"]
</pre>
<p>Notice we also have an address property that points to a dictionary. If want to get the street property inside of address, we can drill down the same way:</p>
<pre lang="swift">
var streetAddresses = items.map({ $0["address"]!["street"] as String})
</pre>
<p>Now, you can see we had to force-unwrap the address property in order to access the street property. This works perfectly and is a fine replacement for valueForKeyPath: of old. When the call succeeds we now have all of the street addresses in the streetAddresses array:</p>
<pre lang="swift">
["111 Main Street", "2277 AB Street", "22311 Place Ave.", "10 Orange Rd."]
</pre>
<p>Take a look at the <a href="https://www.cimgf.com/wp-content/uploads/2014/11/VFKPlayground.playground1.zip">Value For Key Path Playground</a> if you want to see it in action.</p>
<h2>What About Safety?</h2>
<p>In Objective-C, if you message nil, it&#8217;s a no-op. In Swift, however, if we unwrap an optional that is nil, we will crash. So, on this line:</p>
<pre lang="swift">
var streetAddresses = items.map({ $0["address"]!["street"] as String})
</pre>
<p>when we unwrap using the bang ! operator, if that value doesn&#8217;t exist, we&#8217;re in trouble. Say our data was changed to this:</p>
<pre lang="swift">
var items = [
    ["first" : "Billy", "last" : "Bogart", "addr" : ["street" : "111 Main Street"]],
    ["first" : "Gary", "last" : "Gollum", "addr" : ["street" : "2277 AB Street"]],
    ["first" : "David", "last" : "Dangerly", "addr" : ["street" : "22311 Place Ave."]],
    ["first" : "Johnny", "last" : "Jones", "addr" : ["street" : "10 Orange Rd."]]
]
</pre>
<p>Notice the address field has been changed to addr. This causes a crash.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2014/11/playgroundcrash.png"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2014/11/playgroundcrash-300x22.png" alt="Playground Crash" width="300" height="22" class="alignleft size-medium wp-image-2398" srcset="https://www.cimgf.com/wp-content/uploads/2014/11/playgroundcrash-300x22.png 300w, https://www.cimgf.com/wp-content/uploads/2014/11/playgroundcrash-1024x78.png 1024w, https://www.cimgf.com/wp-content/uploads/2014/11/playgroundcrash.png 1466w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Meanwhile, with the old Foundation way, we do this:</p>
<pre lang="swift">
var oldStreetAddresses = (items as NSArray).valueForKeyPath("address.street") as NSArray
</pre>
<p>but look what the output is. NSNull!</p>
<pre lang="swift">
[NSNull, NSNull, NSNull, NSNull]
</pre>
<p>No crash. So which is better?</p>
<p>Well, if your data can be unpredictable, which really shouldn&#8217;t happen, then the Foundation outcome is &#8220;safer&#8221; from a crash perspective. However, your data should be nailed down, so a crash would actually tell you what&#8217;s wrong with your data pretty quickly.</p>
<p>What, though, is the safe Swift way of handling this? We can coerce our objects to optionals and use optional chaining instead:</p>
<pre lang="swift">
var streetAddresses = items.map({ $0["address"]?["street"] as? String})
</pre>
<p>So our first optional operator says to return the object or nil and the second operator says that is should be an optional of type String. This call returns an array of optionals that has this output in our playground:</p>
<pre lang="swift">
[nil, nil, {Some "22311 Place Ave."}, {Some "10 Orange Rd."}]
</pre>
<p>Assuming the following data:</p>
<pre lang="swift">
var items = [
    ["first" : "Billy", "last" : "Bogart", "addr" : ["street" : "111 Main Street"]],
    ["first" : "Gary", "last" : "Gollum", "addr" : ["street" : "2277 AB Street"]],
    ["first" : "David", "last" : "Dangerly", "address" : ["street" : "22311 Place Ave."]],
    ["first" : "Johnny", "last" : "Jones", "address" : ["street" : "10 Orange Rd."]]
]
</pre>
<p>Notice the first two use the bad addr field and the last two use the correct address field.</p>
<p>For my applications, I think I would prefer to see a crash so I know my data is bad. It&#8217;s the server developer&#8217;s problem. Am I right? ;-)</p>
<h2>Taking Map() Farther</h2>
<p>The map() function really goes far beyond this trivial little valueForKeyPath: replacement example. You can really massage your data into any form you want with it. Say for example you wanted to create an transformed array of dictionaries from your array of dictionaries that had some of the same data, but organized differently. For example:</p>
<pre lang="swift">
var fullNames = items.map({ ["full_name" : ($0["first"] as? String)! + " " + ($0["last"] as? String)!] })
</pre>
<p>This returns an array of dictionaries that contain a single key value pair with a key called full_name and value of the first name and last name of each item in the original array concatenated together. The output looks like this in our playground:</p>
<pre lang="swift">
[["full_name": "Billy Bogart"], ["full_name": "Gary Gollum"], ["full_name": "David Dangerly"], ["full_name": "Johnny Jones"]]
</pre>
<p>As you can see, there really are a lot of possibilities for massaging your data structures using map. The tough part is imagining how it might be used and often that just comes from experience. The more you use it, the more obvious the solutions will become.</p>
<h2>Swift Is Not So Bad</h2>
<p>There are certain complaints about Swift I still have, however, I am finding that it is growing on me. I am starting to have much more success making my code pure Swift&#8211;pulling back from my old habits and considering how problems should be solved in this brave new Swift world. It&#8217;s getting better and some of the language aspects are actually better than Objective-C. I couldn&#8217;t see that forest for the trees just a couple short months ago. Until next time.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Protocols in Swift With Core Data</title>
		<link>https://www.cimgf.com/2014/10/29/protocols-in-swift-with-core-data/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Wed, 29 Oct 2014 16:52:07 +0000</pubDate>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2382</guid>

					<description><![CDATA[Sometimes you have a set of objects you want to display in the same form&#8211;say, for example, in a table view controller. What if those objects have, by design, nothing in common and nothing to do with each other? This is a case where you can create and conform to a protocol&#8211;known in some languages [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Sometimes you have a set of objects you want to display in the same form&#8211;say, for example, in a table view controller. What if those objects have, by design, nothing in common and nothing to do with each other? This is a case where you can create and conform to a protocol&#8211;known in some languages as an interface&#8211;to provide a simple way to have each class type provide a display name that can be displayed in your table view controller.</p>
<p>Recently while using this language feature writing Swift code, I ran into a few snags and learned from the process. I figured I would document it in this screencast. It walks you all the way through from project creation, so it&#8217;s about 35 minutes.</p>
<p>Here&#8217;s what you will learn:</p>
<ul>
<li>How to setup CoreData entities in the data model</li>
<li>How to add a run script action to build your managed object classes using mogenerator</li>
<li>How to create a protocol in Xcode 6</li>
<li>How to implement a protocol in the various managed object classes</li>
<li>How to preload your CoreData store with test objects in code</li>
<li>How to load each object type generically into a table view controller</li>
</ul>
<p>And if you want to just cut to the chase, <a href="https://github.com/perlmunger/Proto">grab the code from github</a>.</p>
<p><iframe loading="lazy" src="//player.vimeo.com/video/110260560" width="500" height="313" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p>
<p><a href="http://vimeo.com/110260560">Protocols in Swift With Core Data</a> from <a href="http://vimeo.com/user2563726">Skye Road Systems</a> on <a href="https://vimeo.com">Vimeo</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Core Data stack in Swift</title>
		<link>https://www.cimgf.com/2014/06/08/the-core-data-stack-in-swift/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Sun, 08 Jun 2014 20:47:22 +0000</pubDate>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2341</guid>

					<description><![CDATA[Whenever Apple releases a new version of Xcode one of the first things that I do is look at the default templates and see if there are any new or interesting things. This year, with the release of Swift, there are some pretty radical changes. Yet the Core Data stack initialization code is still the [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2014/06/swift-hero.png" alt="swift-hero" width="128" height="128" align="left"/>Whenever Apple releases a new version of Xcode one of the first things that I do is look at the default templates and see if there are any new or interesting things.</p>
<p>This year, with the release of <a href="https://developer.apple.com/swift/">Swift</a>, there are some pretty radical changes.  Yet the Core Data stack initialization code is still the same.</p>
<p>There is nothing <em>wrong</em> with the default template code but there isn&#8217;t really anything right about it either.  It is far better than it once was but it is still overly verbose and hard to follow.</p>
<p>Therefore, I present my Swift Core Data stack code that I will be using as I grok this language.</p>
<p><span id="more-2341"></span></p>
<h2><code>saveContext()</code></h2>
<pre><code>func saveContext () {
  var error: NSError? = nil
  let moc = self.managedObjectContext
  if moc == nil {
    return
  }
  if !managedObjectContext.hasChanges {
    return
  }
  if managedObjectContext.save(&amp;error) {
    return
  }

  println("Error saving context: \(error?.localizedDescription)\n\(error?.userInfo)")
  abort()
}
</code></pre>
<p>The save method is always the first one that I attack. I strongly dislike having conditions inside of conditions inside of conditions.  It is ugly and hard to follow.  I much prefer the fail early, fail often design.  In my version of the <code>saveContext()</code> we do just that.  Every opportunity to fail (or finish) is exercised individually and if it is a failure or finish condition, we return.</p>
<p>All of the logic is on the left side and easy to follow.</p>
<h2><code>managedObjectContext</code> (Version 2)</h2>
<p>Next up is the stack itself.  Apple creates four variables when we really only use one.  It is rare to use <code>persistentStoreCoordinator</code> more than once in the life cycle of an application and even more rare to use <code>managedObjectModel</code> more than once.  So why have individual variables for them?  This is even more wasteful when you realize that both are accessible from the <code>managedObjectContext</code>.  Therefore, I prefer to roll them into one, fairly easy to follow variable.</p>
<pre><code>@lazy var managedObjectContext: NSManagedObjectContext = {
  let modelURL = NSBundle.mainBundle().URLForResource("SwiftTestOne", withExtension: "momd")
  let mom = NSManagedObjectModel(contentsOfURL: modelURL)
  ZAssert(mom != nil, "Error initializing mom from: \(modelURL)")

  let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)

  let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
  let storeURL = (urls[urls.endIndex-1]).URLByAppendingPathComponent("SwiftTestOne.sqlite")

  var error: NSError? = nil

  var store = psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &amp;error)
  if (store == nil) {
    println("Failed to load store")
  }
  ZAssert(store != nil, "Unresolved error \(error?.localizedDescription), \(error?.userInfo)\nAttempted to create store at \(storeURL)")

  var managedObjectContext = NSManagedObjectContext()
  managedObjectContext.persistentStoreCoordinator = psc

  return managedObjectContext
}()
</code></pre>
<p>Apple&#8217;s sample code uses two variables, one that is calculated and then one &#8220;private&#8221; variable that actually holds the reference.  Thanks to lots of feedback from other developers we have a more elegant solution.  A lazily loaded var.  This simplifies the code quite a bit.</p>
<p>Inside of the getter is where all of the code from the other functions exist.  We first grab the URL for the model and then pass that URL into the <code>NSManagedObjectModel</code>.  We then test to make sure that the <code>NSManagedObjectModel</code> initialized properly.  Right now ZAssert is a global function that is tied to a constant Bool to determine how it reacts to failure.  I am still playing with that part so it is not fixed in stone and will get its own blog post once I am happy with it.  For now it looks like:</p>
<pre><code>let DEBUG = true

func ZAssert(test: Bool, message: String) {
  if (test) {
    return
  }

  println(message)

  if (!DEBUG) {
    return
  }

  var exception = NSException()
  exception.raise()
}
</code></pre>
<p>Note that we are creating <code>mom</code> as a constant. We know this object is not going to change for us so we don&#8217;t need to create it as a variable.  Having constant objects like this is a pretty cool feature of Swift.</p>
<p>Once we know the <code>NSManagedObjectModel</code> has been initialized properly we can move on to our <code>NSPersistentStoreCoordinator</code>.  Creating the <code>NSPersistentStoreCoordinator</code> is just a matter of passing in the initialized <code>NSManagedObjectModel</code> that we just created.  We create the <code>NSPersistentStoreCoordinator</code> as another constant.  Next we need to load a <code>NSPersistentStore</code> into the <code>NSPersistentStoreCoordinator</code>.</p>
<p>To do that we need to know where the store is going to be saved.  We grab all of the possible locations for the documents directory and select the last one from the returned array.  We can then append the filename of our store to the end of the <code>NSURL</code>.</p>
<p>With a location we can now ask the <code>NSPersistentStoreCoordinator</code> to add a store for that location.  We call the method <code>addPersistentStoreWithType</code> on the <code>NSPersistentStoreCoordinator</code> and we get back either a <code>NSPersistentStore</code> or nothing.  If we get nothing back then that is a failure which we check for.</p>
<p>Finally after the <code>NSPersistentStore</code> has been created we can create the actual <code>NSManagedObjectContext</code>.  We just initialize the <code>NSManagedObjectContext</code>, hand it the <code>NSPersistentStoreCoordinator</code> and return.</p>
<h2>Wrap Up</h2>
<p>This has changed about three times already and will probably change again.  I am not crazy about how the <code>storeURL</code> is being constructed and will probably clean that up as I go forward.  I am certain my <code>ZAssert</code> is going to change.</p>
<p>If you have any suggestions on how to improve, simplify this, please shoot me an email at the usual place.  Hopefully we can get down to the infamous five lines of code soon.  Right now we are sitting at about 8 (we started around 11)&#8230;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Deleting Objects in Core Data</title>
		<link>https://www.cimgf.com/2014/02/25/deleting-objects-in-core-data/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Tue, 25 Feb 2014 21:11:07 +0000</pubDate>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Rants]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2335</guid>

					<description><![CDATA[I very rarely speak out against another blog post. I find the resulting argument back and forth draining. However, there are exceptions and one occurred over the weekend. Brent Simmons has been blogging about his conversion of Vesper to a Core Data application. A recent post of his titled Core Data and Deleting Objects set [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I very rarely speak out against another blog post.  I find the resulting argument back and forth draining.  However, there are exceptions and one occurred over the weekend.</p>
<p>Brent Simmons has been blogging about his conversion of Vesper to a Core Data application.  A recent post of his titled <a href="http://inessential.com/2014/02/22/core_data_and_deleting_objects">Core Data and Deleting Objects</a> set my teeth on edge. Brent says:</p>
<p>&#8220;The best advice I’ve heard about deleting managed objects is to 1) not do it, or 2) do it only at startup, before any references to those to-be-deleted objects can be made.&#8221;</p>
<p>I do not know who is giving Brent advice but he must be playing tricks with him or just trying to wind him up.  The advice was simple; don&#8217;t delete Core Data objects or if you are going to delete them, delete them at launch.</p>
<p>Will that work? Sure. Is it the right answer? Not even close.</p>
<p><span id="more-2335"></span></p>
<p>Advice like this comes from mistakes.  Mistakes in application design.  Mistakes in application planning.  Someone, somewhere, coded himself into a corner and decided that Core Data was to blame.  I hear this a lot.  It is one of the common conversation starters I have with new clients.</p>
<p>So what is the right answer?  Plan your application out.  Plan your application for deleting objects.</p>
<p>When we are talking about working on iOS the easiest way to handle this is to use the built in tools that the framework already provides for you.  Use the <code>NSFetchedResultsController</code>.  Use it everywhere it makes sense.  Squeeze it into places that it kind of makes sense. Why? It watches the <code>NSManagedObjectContext</code> for you!  It will tell you when an object has been inserted, updated or deleted!  It is like magic!</p>
<p>Don&#8217;t like it or it doesn&#8217;t fit for you?  Build your own! Seriously, the core of the <code>NSFetchedResultsController</code> is not hard at all.  Here is a very basic one that just watches for deletes:</p>
<pre><code>//
//  MCDeleteWatcher.h
//  MCDeleteWatcher
//
//  Created by Marcus S. Zarra on 2/24/14.
//  Copyright (c) 2014 MartianCraft. All rights reserved.
//  Permission is hereby granted, free of charge, to any person
//  obtaining a copy of this software and associated documentation
//  files (the "Software"), to deal in the Software without
//  restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following
//  conditions:
//
//  The above copyright notice and this permission notice shall be
//  included in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//  OTHER DEALINGS IN THE SOFTWARE.
//

typedef void (^DeletedObjectsBlock)(NSSet *deletedObjects);

@interface MCDeleteWatcher : NSObject

@property (copy) DeletedObjectsBlock deletedObjectsBlock;

- (id)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator*)psc;

- (void)addObjectToWatch:(NSManagedObject*)object;
- (void)addObjectsToWatch:(NSArray*)objects;

@end

//
//  MCDeleteWatcher.m
//  MCDeleteWatcher
//
//  Created by Marcus S. Zarra on 2/24/14.
//  Copyright (c) 2014 MartianCraft. All rights reserved.
//  Permission is hereby granted, free of charge, to any person
//  obtaining a copy of this software and associated documentation
//  files (the "Software"), to deal in the Software without
//  restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following
//  conditions:
//
//  The above copyright notice and this permission notice shall be
//  included in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//  OTHER DEALINGS IN THE SOFTWARE.
//
#import "MCDeleteWatcher.h"

@interface MCDeleteWatcher()

@property (weak) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (strong) NSMutableSet *objectsToWatch;

@end

@implementation MCDeleteWatcher

- (id)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator*)psc;
{
  ZAssert(psc, @"PSC is nil!");
  ZAssert([NSThread isMainThread], @"Initialization must be on main thread");

  if (!(self = [super init])) return nil;

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextUpdated:) name:NSManagedObjectContextObjectsDidChangeNotification object:nil];

  [self setPersistentStoreCoordinator:psc];
  [self setObjectsToWatch:[NSMutableSet set]];

  return self;
}

- (void)dealloc
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)addObjectToWatch:(NSManagedObject*)object;
{
  [[self objectsToWatch] addObject:object];
}

- (void)addObjectsToWatch:(NSArray*)objects;
{
  [[self objectsToWatch] addObjectsFromArray:objects];
}

- (void)contextUpdated:(NSNotification*)notification
{
  if (![self deletedObjectsBlock]) return;

  if ([[notification object] persistentStoreCoordinator] != [self persistentStoreCoordinator]) return;

  NSSet *deleted = [[notification userInfo] objectForKey:NSDeletedObjectsKey];
  if (![[self objectsToWatch] intersectsSet:deleted]) return;

  NSMutableSet *objectsDeleted = [NSMutableSet set];
  for (NSManagedObject *object in deleted) {
    if ([[self objectsToWatch] containsObject:object]) [objectsDeleted addObject:object];
  }

  if ([NSThread isMainThread]) {
    [self deletedObjectsBlock](objectsDeleted);
  } else {
    dispatch_async(dispatch_get_main_queue(), ^{
      [self deletedObjectsBlock](objectsDeleted);
    });
  }
}

@end
</code></pre>
<p>So why are deleted <code>NSManagedObject</code> instances so dangerous?  Well it depends on your version of Core Data.  Prior to iOS 5 (meaning iOS 3 and 4) if you tried to access a property on a deleted <code>NSManagedObject</code> instance you would get an immediate exception of &#8220;CoreData could not fulfill a fault&#8221; which would result in your application crashing.</p>
<p>I like to pretend that iOS 5 never happened.</p>
<p>In iOS 6 and 7, accessing the property will not cause a crash. You will just get <code>nil</code> back which can be unexpected.  However if you try and set a property, you get the familiar crash.</p>
<p>How do we avoid this edge case?  Well, it is kind of like memory management, when you have released the object (aka deleted it) <strong>don&#8217;t touch it again!</strong></p>
<p>Watch for notifications on objects that can be deleted under you.  React to those notifications.  Plan for them.  Presenting an edit view and the object is deleted? React!</p>
<p>If you are in legacy code and need to test for an object to see if it was deleted from under you and the ripple is too large to do it right then you can ask the object <code>-isDeleted</code> and you can also test for the <code>NSManagedObjectContext</code> being <code>nil</code>.</p>
<p>Be warned though.  <code>-isDeleted</code> really should be called <code>-isScheduledForDeletion</code> as it will only return <code>YES</code> if the object <em>will be</em> deleted during the next save.  Once the <code>NSManagedObjectContext</code> has been saved it will return <code>NO</code>.</p>
<p>Testing <code>-managedObjectContext</code> for <code>nil</code> also has a catch. There are multiple situations where the <code>-managedObjectContext</code> property of a <code>NSManagedObject</code> can be <code>nil</code>. For example, you can create a <code>NSManagedObject</code> without a context. Therefore this is not an absolute test either.</p>
<p>You can also play around with <code>-[NSManagdObjectContext existingObjectWithID:error:]</code> if you want.</p>
<p><strong>These are a code smells</strong>.</p>
<p>Your application should be handling deletes properly and should know that the object has been deleted and react to it.  Waiting until you are on the edge of the cliff and then asking the now-deleted object if it has been deleted is bad.</p>
<p>What is the right answer?</p>
<p><strong>Plan for deletions</strong>.</p>
<p>Core Data is a framework with a nearly impossible job.  Writing a universal persistence engine is right up there with solving PI.  You can go really deep but you are never going to &#8220;solve it&#8221;.  Eventually it is &#8220;good enough&#8221; and has edge cases.</p>
<p>There is a reason Brent keeps coming back to Core Data.  Writing your own persistence engine is more trouble than it is worth.  Better to use an existing framework that has a team of highly skilled engineers working on it than to write your own.  Yes it will have edges.  Yes it can break.  But it is better than the alternative 99.999% of the time.</p>
<p>Our job as developers is to learn where those edges are and plan for them.</p>
<p>Don&#8217;t scream in the darkness; learn how to turn on the light.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fetched Properties; useful?</title>
		<link>https://www.cimgf.com/2014/01/01/fetched-properties-useful/</link>
		
		<dc:creator><![CDATA[Marcus Zarra]]></dc:creator>
		<pubDate>Wed, 01 Jan 2014 22:32:42 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2330</guid>

					<description><![CDATA[Core Data has a number of features and abilities that are not commonly used. Chief among those are fetched properties. In discussing them with a number of developers, most have never heard of them and those who have heard of them couldn&#8217;t come up with a viable use case for them. To be honest, I [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Core Data has a number of features and abilities that are not commonly used.  Chief among those are fetched properties. In discussing them with a number of developers, most have never heard of them and those who have heard of them couldn&#8217;t come up with a viable use case for them.</p>
<p>To be honest, I don&#8217;t have a lot of use cases for them myself.  They are definitely not one of the core features of Core Data that I recommend people learning when they are initially getting comfortable with the framework.</p>
<p>In this article we will discuss one use case for fetched properties and the impacts.</p>
<p>## The Use Case</p>
<p>The use case for fetched properties that I have run across a few times comes into play when you have more than one persistent store file on disk.  Imagine you are building a recipe application (one of my favorite examples).  You decide to include a pre-built read-only database with existing recipes. However, your application has the ability to add notes and social comments to a recipe.  </p>
<p>You want to keep the recipe database as read only (you have a separate one for new recipes) but you want the user to be able to add comments.  Where do we put the data?</p>
<p>In this contrived situation, storing the comments (and other metadata) in another store makes sense.  Unfortunately we can&#8217;t have relationships across physically separate stores.  </p>
<p>Enter the Fetched Property.</p>
<p>## Fetched Property</p>
<p>A fetched property is a property added to a `NSManagedObject` entity that instead of storing a value or a relationship, it stores a `NSFetchRequest`.  When the property is accessed for the first time the `NSFetchRequest` is fired and the results are returned.</p>
<p>A fetched property always returns a `NSArray` (well a subclass but that is a minor detail) and it can be configured to sort the results.</p>
<p>Unfortunately, the editor in Xcode does not permit adding sort criteria so the only way to add a sort to a fetched property is to create the fetched property in code.  Hopefully that will be corrected in some future release of Xcode.</p>
<p>What does a fetched property look like?  In the Core Data model editor, a fetched property is added just like an attribute or a relationship.  Then in the Data Model inspector you can configure the `NSFetchRequest`.</p>
<div id="attachment_2332" style="width: 310px" class="wp-caption aligncenter"><a href="https://www.cimgf.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-19-at-9.14.59-PM.png"><img aria-describedby="caption-attachment-2332" loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-19-at-9.14.59-PM-300x149.png" alt="A Fetched Property shown in Xcode&#039;s data modeler" width="300" height="149" class="size-medium wp-image-2332" srcset="https://www.cimgf.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-19-at-9.14.59-PM-300x149.png 300w, https://www.cimgf.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-19-at-9.14.59-PM-1024x508.png 1024w, https://www.cimgf.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-19-at-9.14.59-PM-900x447.png 900w, https://www.cimgf.com/wp-content/uploads/2014/01/Screen-Shot-2013-12-19-at-9.14.59-PM.png 1336w" sizes="(max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2332" class="wp-caption-text">A Fetched Property shown in Xcode&#8217;s data modeler</p></div>
<p>The Destination is the entity that will be returned by the fetched property.  The predicate is a string representation of the `NSPredicate` configured within the `NSFetchRequest`.  </p>
<p>Further, the predicate can use one of two variables to help configure it:</p>
<p>`$FETCH_SOURCE` gets replaced by a reference to the entity that owns the fetched property.  By using this variable we can reference properties in the owning entity.</p>
<p>`$FETCHED_PROPERTY` gets replaced by a reference to the the property description of the fetched property.  The property description includes key value pairs that are accessible from within the predicate. I have not run across a situation where I have used this variable.</p>
<p>## The sharp edges</p>
<p>There are unfortunately some concerns with fetched properties.  </p>
<p>Unlike a relationship, there is no way to pre-fetch a fetched property.  Therefore, if you are going to fetch a large number of entities and then desire to access the fetched property for those properties, they are going to be fetched individually.  This will drastically impact performance.</p>
<p>Fetched Properties are only fetched once per context without a reset.  This means that if you add other objects that would qualify for the fetched property after the property has been fetched then they won&#8217;t be included if you call the fetched property again.  To *reset* the fetched property requires a call to `-refreshObject:mergeChanges:`.</p>
<p>A fetched property always returns an array.  While this is not a major issue if in fact you want more than one object returned.  However, when that is not the case it is an additional method call that you need to make every time or add a convenience method.  More code equals more bugs.</p>
<p>## To use or not to use</p>
<p>Fetched properties are not a main line piece of Core Data.  It appears that even the Core Data team (or the Xcode team at least) agrees with that assessment based on how little effort is given to them in the model editor.  Should you use them?</p>
<p>It depends.  If you are joining two separate persistent stores and need a *soft* relationship between entities in those stores then yes, you can use them.  They do work. </p>
<p>Be mindful of the edges, they are sharp.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automating OS X app test build distribution across multiple OS versions</title>
		<link>https://www.cimgf.com/2013/12/17/automating-os-x-app-test-build-distribution-across-multiple-os-versions/</link>
		
		<dc:creator><![CDATA[Fraser Hess]]></dc:creator>
		<pubDate>Tue, 17 Dec 2013 18:21:08 +0000</pubDate>
				<category><![CDATA[App Distribution]]></category>
		<category><![CDATA[Development Environment]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2287</guid>

					<description><![CDATA[With Apple now shipping OS X upgrades every 12-15 months, Mac developers are very quickly finding themselves supporting their apps on multiple OS X versions. Until recently, my approach to testing on multiple OS X versions involved partitioning an external USB drive and installing the OS X versions onto it and booting off the partitions [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>With Apple now shipping OS X upgrades every 12-15 months, Mac developers are very quickly finding themselves supporting their apps on multiple OS X versions. Until recently, my approach to testing on multiple OS X versions involved partitioning an external USB drive and installing the OS X versions onto it and booting off the partitions to test.</p>
<p>While this approach is inexpensive, the test-discover-reboot-fix-build-test cycle just got to be too much for even this frugal Scot.</p>
<p><strong>Enter the Mac mini</strong></p>
<p>My new solution has 2 parts: a maxed out Mac mini with VMware Fusion to support all the targeted OS X versions and a scripted piece that will sync new test builds to the VMs.</p>
<p>The current $799 Mac mini has a quad-core Intel Core i7, a 1TB HD and is expandable to 16GB of RAM. Our local MicroCenter had a $749 sale on that model so I picked one up along with a 16GB RAM upgrade. After I setup 4 VMs, one for each of 10.6 &#8211; 10.9, I found the performance to be incredibly slow. Analyzing the issue quickly identified the speed of the stock HD as a bottleneck, so after considering returning the whole kit for a BTO Fusion Drive model, I picked up an OWC 240GB Mercury EXTREME<img src="https://s.w.org/images/core/emoji/13.1.0/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pro 6G SSD, and now the performance is great. (Installing an extra HD in a Mac mini is possible, but if you do, make sure you watch and understand the videos on the topic and make sure you order the correct parts to install in your Mac mini.)</p>
<p><strong>Moving the builds around</strong></p>
<p>Each of my Mac Xcode projects now has an extra scheme called <em>MyApp test build</em>. The following scheme settings are used: In <strong>Run MyApp.app</strong>, I&#8217;m using the <strong>Release</strong> build configuration and I&#8217;ve set <strong>Launch</strong> to <strong>Wait for MyApp.app to launch</strong> since I don&#8217;t intend to run these builds from Xcode. Most importantly, in <strong>Build->Post Actions</strong>, I&#8217;ve added a <strong>Run Script Action</strong> with <strong>Provide build settings from</strong> set to the app. The script below creates a new uniquely-named folder in the <code>$root_destination_folder</code> every time you build and will copy the resulting product into that newly created folder. The folder name combines date/time, product name, and the current <code>git describe</code>. The <code>$root_destination_folder</code> should be in a folder that is synced by a service. I used Dropbox at first, but it doesn&#8217;t seem optimized for the large number of small files that compose a Mac application bundle, even with LAN syncing turned on. I&#8217;m now using <a href="http://bittorrent.com/sync">BitTorrent Sync</a>, which uses the BitTorrent protocol. Even as a beta release, I had great success with it. By adding the shared folder to the BitTorrent Sync client on each test VM, every time I make a test build, it automatically appears on each VM.</p>
<p>By running multiple OS X versions in VMs simultaneously and syncing test builds, I&#8217;ve nearly eliminated all the waiting involved in testing and iterating across multiple OS X versions.</p>
<pre lang='bash'>
root_destination_folder=/Users/fraser/Development/test_builds_sync
date=`date +%Y%m%d-%H%M%S`
product=$PRODUCT_NAME
git=/usr/bin/git
cd $SRCROOT
version=`$git describe --dirty`
full_dir_path=$root_destination_folder/$date-$product-$version
mkdir -p $full_dir_path
cp -RH $TARGET_BUILD_DIR/$FULL_PRODUCT_NAME $full_dir_path
</pre>
<p>Note 1: For testing on Mac OS X 10.6 Snow Leopard, only Snow Leopard Server is supported in VMware Fusion. Apple has made Snow Leopard Server available to paid Mac developers as a free download. The provided serial number expires at the end of 2014.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using GIT In Xcode</title>
		<link>https://www.cimgf.com/2013/12/10/using-git-in-xcode/</link>
		
		<dc:creator><![CDATA[Joe Keeley]]></dc:creator>
		<pubDate>Tue, 10 Dec 2013 06:50:31 +0000</pubDate>
				<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Undocumented]]></category>
		<category><![CDATA[Version Control]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2213</guid>

					<description><![CDATA[Git has become a very popular version control system in iOS and Mac development. Git comes with a set of command line tools to check status, commit changes, view logs, make and merge branches, and coordinate commits with a remote repository.  There are a number of desktop apps that can perform these functions, including Xcode.  [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Git has become a very popular version control system in iOS and Mac development. Git comes with a set of command line tools to check status, commit changes, view logs, make and merge branches, and coordinate commits with a remote repository.  There are a number of desktop apps that can perform these functions, including Xcode.  When I ask other iOS and Mac developers how they interact with Git, most say they use the command line or a separate desktop app like Tower.  I find very few developers use Xcode for even some basic Git tasks, and many developers are not aware of the Git support Xcode offers.</p>
<p>For my own workflow, I like to minimize the number of tools used and number of switches between apps needed to complete a task.  So, I decided to attempt to use Xcode exclusively to interact with Git and share my results.  So far I have been pleasantly surprised at what all Xcode can do with Git. If you have not taken a look at Xcode’s support for Git, you may be surprised how much you can accomplish.</p>
<p>This article assumes basic familiarity with Xcode and Git, and describes Git functionality present in Xcode version 4.6.2.<span id="more-2213"></span></p>
<h2>NEW GIT PROJECT SETUP IN XCODE</h2>
<p>Since Git is a distributed version control system, a repository can be created locally when starting a project, or on a remote server and then cloned.  Xcode can handle both situations.</p>
<p>When creating a new Xcode project, you can include a local git repository by checking the “Create local git repository for this project” option.  Xcode will initialize the repository and perform an initial commit with the template files for you.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_1.png"><img loading="lazy" class="alignnone size-medium wp-image-2221" alt="git_xcode_1" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_1-300x89.png" width="300" height="89" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_1-300x89.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_1.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>If you are sharing your project with a team or just want a backup of your project on another machine, you can set up a remote copy of the repository.  The typical way this is done is to create an empty repository on a git service like GitHub or Bitbucket.  Once the repository is available, return to Xcode and open the Organizer. Select Repositories to view all the version control repositories that Xcode is aware of, and find the new project repository.  Select Remotes for the new project, add then click the Add Remote button.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_2.png"><img loading="lazy" class="alignnone size-medium wp-image-2224" alt="git_xcode_2" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_2-300x81.png" width="300" height="81" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_2-300x81.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_2.png 814w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Xcode will present a dialog to add the remote. You can follow the default naming standard for a git remote and give it the name “origin”, or you use a custom name.  Then specify the remote URL for the repository, which will be provided by Bitbucket.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_3.png"><img loading="lazy" class="alignnone size-medium wp-image-2225" alt="git_xcode_3" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_3-300x202.png" width="300" height="202" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_3-300x202.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_3.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>If the remote repository is private and requires authentication, you can enter it after the remote is added.  Select the remote in the Organizer list, and an authentication interface will appear below the list.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_4.png"><img loading="lazy" class="alignnone size-medium wp-image-2226" alt="git_xcode_4" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_4-300x100.png" width="300" height="100" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_4-300x100.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_4.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Once the remote is added and authentication provided, the master branch needs to be pushed to it.  Return to the Xcode project window.  From the Xcode menu, select File | Source Code | Push&#8230; Xcode will present a sheet which will allow you to select a remote to push to, and a branch to push.  Note that Xcode has checked with the remote repository, and indicates that the master branch will be created in the remote repository with the push.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_5.png"><img loading="lazy" class="alignnone size-medium wp-image-2227" alt="git_xcode_5" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_5-300x112.png" width="300" height="112" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_5-300x112.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_5.png 952w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Once the push is complete, the remote repository is available for updates and for other users.</p>
<h2>USING AN EXISTING REMOTE PROJECT IN XCODE</h2>
<p>To clone a copy of an existing remote repository, open the Organizer in Xcode and select Repositories.  Click the plus (“+”) button in the lower left hand corner of the Organizer, and select “Checkout or Clone Repository&#8230;”.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_6.png"><img loading="lazy" class="alignnone size-medium wp-image-2228" alt="git_xcode_6" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_6-300x107.png" width="300" height="107" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_6-300x107.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_6.png 516w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Xcode will present a dialog requesting a URL or file path.  Xcode can handle both ssh and https URLs for git repositories.  Be sure to specify the full URL for the repository, which is typically available on the project page for Github or Bitbucket.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_7.png"><img loading="lazy" class="alignnone size-medium wp-image-2229" alt="git_xcode_7" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_7-300x203.png" width="300" height="203" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_7-300x203.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_7.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>If the repository is private and requires authentication, Xcode will request your credentials for the repository.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_8.png"><img loading="lazy" class="alignnone size-medium wp-image-2230" alt="git_xcode_8" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_8-300x137.png" width="300" height="137" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_8-300x137.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_8.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Provide your credentials and click OK.  Xcode will store your credentials in the keychain for subsequent accesses of the remote repository.  Note that Xcode can also handle ssh key authentication in addition to name and password.  Once Xcode has authenticated with the remote repository, Xcode will request a location to store the project, and then project will be cloned.  Once cloned the project can be opened or shown in the finder.</p>
<p>If you run into an issue with using the Checkout or Clone approach and authentication, Select “Add Repository&#8230;” instead.  You can then add your authentication information for the repository, and clone from there.  This approach worked for me in cases where using Checkout or Clone did not.</p>
<p>When the clone is complete, the local working copy is ready for updates.</p>
<h2>MAKING AND COMMITTING CHANGES</h2>
<p>Once you have a working copy of your project, it’s time to get to work.  As you make changes to the project, Xcode will indicate when files have been changed from the working copy.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_9.png"><img loading="lazy" class="alignnone size-medium wp-image-2231" alt="git_xcode_9" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_9-300x282.png" width="300" height="282" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_9-300x282.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_9.png 558w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>An “M” next to a file indicates it has been modified, and an “A” indicates the file is new to the repository.</p>
<p>To commit changes, select File | Source Control | Commit from the Xcode menu.  Xcode will display all the differences from the working copy in the commit view.  If you only want to commit some of the changes, you can check or uncheck files as desired to include or exclude them from the commit.  In addition, you can select only the files you want to commit before selecting File | Source Control | Commit from the Xcode menu, and only the files you have selected will be displayed in the commit view.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_10.png"><img loading="lazy" class="alignnone size-medium wp-image-2232" alt="git_xcode_10" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_10-300x156.png" width="300" height="156" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_10-300x156.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_10.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>In this example, I have added a label to the storyboard with a corresponding property in the view controller, and have added a new class to the project.  I only want to commit the label changes, so I have selected those and added a commit message in the bottom section.  In addition to making file level selections for a commit, Xcode can do line level selections for a commit.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_111.png"><img loading="lazy" class="alignnone size-medium wp-image-2233" alt="git_xcode_11" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_111-300x155.png" width="300" height="155" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_111-300x155.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_111.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>In this example, I have work in progress in myExperimentalMethod, but I have added the desired functionality to myNewMethod and would like to commit so other members of the team can use it while I finish myExperimentalMethod.  By clicking on the numbers in the center column I can select whether a change should be included in or excluded from the commit, or I can discard the change.</p>
<p>Note that Xcode will not show deleted files that have been removed from the project.  When a file is deleted from an Xcode project, the project will indicate that the project has been modified, but the file will no longer be visible in the Xcode project view.  The deleted file will be staged for the next commit and will be included in the next commit, but it will not be visible in the project view or the commit view.</p>
<h2>LOOKING AT HISTORY</h2>
<p>Xcode provides a Versions editor, which has three different perspectives on the git history for a file.  To use the Versions editor, select the file in the Standard editor in Xcode, the switch to the Versions editor using the editor segmented control in the upper right hand corner of the Xcode window.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_12.png"><img loading="lazy" class="alignnone size-full wp-image-2234" alt="git_xcode_12" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_12.png" width="245" height="125" /></a></p>
<p>The three perspectives are Comparison, Blame, and Log, and can be selected using the segmented control in the lower right portion of the editor pane when the Versions editor is active.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_13.png"><img loading="lazy" class="alignnone size-full wp-image-2235" alt="git_xcode_13" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_13.png" width="260" height="79" /></a></p>
<p>The Comparison view will initially show changes in the working copy from the most recent commit.  Changes can be discarded by clicking on the number in the center column and selecting Discard Change from the menu.  The Comparison view can also compare any two arbitrary commits.  To do this, click the clock icon at the bottom of the center column.  Xcode will present a view of the commits that have taken place for the file.  Adjust the two white pointers to select the version to display in each window.  Xcode will display the commit information for each commit as you move the arrow past it.  Once selected, Xcode will highlight the code differences between the versions.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_14.png"><img loading="lazy" class="alignnone size-medium wp-image-2236" alt="git_xcode_14" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_14-300x189.png" width="300" height="189" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_14-300x189.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_14.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>If something in the code does not make sense or is not clear, it can be helpful to talk to the person who coded it.  Blame view can identify the author of each line of code by showing who made each change in the file, and corresponding commit information for each change.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_15.png"><img loading="lazy" class="alignnone size-medium wp-image-2237" alt="git_xcode_15" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_15-300x105.png" width="300" height="105" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_15-300x105.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_15.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>To see detailed information for each commit, hover over the name and date section and an info button will appear in the far right edge.  Click the info button to see commit information.  Clicking View Changes will show the comparison view that is used for committing for all the files included in that commit.</p>
<p>The Log view will show the history of commits in the right hand side of the view.  Hovering over each commit will display an info button which can be clicked to show the same detailed information about each commit that Blame shows.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_16.png"><img loading="lazy" class="alignnone size-medium wp-image-2238" alt="git_xcode_16" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_16-300x94.png" width="300" height="94" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_16-300x94.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_16.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>In the Repository section of the Organizer, logs are available for both the working copy and branches.  If the working copy is selected, Xcode can even show commits specific to a selected file.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_17.png"><img loading="lazy" class="alignnone size-medium wp-image-2239" alt="git_xcode_17" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_17-300x159.png" width="300" height="159" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_17-300x159.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_17.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>When looking at branches, select a branch to see recent commits for that branch.  For all history, you can expand the commit by clicking on the arrow to the left of the commit hash to see what files were included in the commit, and you can click on the View Changes button to view all the changes in the comparison view.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_18.png"><img loading="lazy" class="alignnone size-medium wp-image-2240" alt="git_xcode_18" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_18-300x160.png" width="300" height="160" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_18-300x160.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_18.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h2>USING BRANCHES</h2>
<p>Branches can be a very effective tool to isolate new features or experiments in code.  Xcode has pretty good support for branches, but it is not shown in the project view.  The first method you can use to commit code to a branch is to select “Commit to Branch&#8230;” instead of “Commit X Files” from the commit view.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_19.png"><img loading="lazy" class="alignnone size-medium wp-image-2241" alt="git_xcode_19" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_19-300x124.png" width="300" height="124" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_19-300x124.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_19.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Xcode will ask you to select a branch to commit to, or will allow you to create a new branch.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_20.png"><img loading="lazy" class="alignnone size-medium wp-image-2242" alt="git_xcode_20" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_20-300x83.png" width="300" height="83" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_20-300x83.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_20.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Once you have committed to a branch from master, you will be automatically switched to that branch.  You can continue making changes and commits to the branch.  So how do you know what branch you are on in Xcode, or get back to the master branch, or switch to another branch?  Visit the Repositories in the Organizer, find the repository for your project, and select the working copy.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_21.png"><img loading="lazy" class="alignnone size-medium wp-image-2243" alt="git_xcode_21" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_21-300x148.png" width="300" height="148" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_21-300x148.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_21.png 370w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>To see what branch you are currently on, look in the upper right hand corner of the Repository view.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_22.png"><img loading="lazy" class="alignnone size-medium wp-image-2244" alt="git_xcode_22" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_22-300x176.png" width="300" height="176" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_22-300x176.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_22.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>To switch back to master or to another branch, click the “Switch Branch” button in the lower right hand corner.  Select another branch, and your Xcode project workspace will be updated to reflect the current contents of the other branch.</p>
<p>When you are ready to merge a branch, switch to the branch you want to merge into first from the Organizer.  Then switch back to the project view,  and select File | Source Control | Merger from the Xcode menu.  Xcode will ask which branch you would like to merge into your current branch.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_23.png"><img loading="lazy" class="alignnone size-medium wp-image-2245" alt="git_xcode_23" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_23-300x101.png" width="300" height="101" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_23-300x101.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_23.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Xcode will then present a merge view, which will allow you to review each difference between the current branch and merge branch.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_24.png"><img loading="lazy" class="alignnone size-medium wp-image-2246" alt="git_xcode_24" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_24-300x155.png" width="300" height="155" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_24-300x155.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_24.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Use the sliders to selectively include or exclude changes from the branch in the merge.</p>
<p>If there is a conflict in the merge, the merge view will highlight the conflict in the merge view with red and a question mark in the center.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_25.png"><img loading="lazy" class="alignnone size-medium wp-image-2247" alt="git_xcode_25" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_25-300x156.png" width="300" height="156" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_25-300x156.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_25.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The merge view will offer four choices for resolving the conflict: keep both changes, placing the left before right, keep only the left changes, keep only the right changes, and keep both changes, placing the right before left.  In addition the code can be directly edited in the merge view.</p>
<h2>KEEPING IN SYNC WITH REMOTE REPOSITORIES</h2>
<p>As you make changes in your local working copy you will want to keep them in sync with the remote repository.  Xcode offers support for pulling from and pushing to a remote repository, and for tracking remote branches.</p>
<p>There are two ways to pull from a remote repository. The first is from the project window.  Select File | Source Control | Pull from the Xcode menu when viewing a project window.   If there are no uncommitted changes in the working copy, Xcode will present a dialog to select which remote and branch to pull from. (Note that a pull can be completed using command line Git when changes are present, but Xcode will not pull with uncommitted changes in the working directory.)</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_26.png"><img loading="lazy" class="alignnone size-medium wp-image-2248" alt="git_xcode_26" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_26-300x110.png" width="300" height="110" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_26-300x110.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_26.png 941w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Alternatively, the Pull button from the Organizer Repositories view can be used when a working copy is selected.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_27.png"><img loading="lazy" class="alignnone size-medium wp-image-2249" alt="git_xcode_27" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_27-300x147.png" width="300" height="147" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_27-300x147.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_27.png 900w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>If a conflict is detected on the pull, Xcode will present the merge viewer to resolve the conflict.  Just like resolving a conflict between branches, the merge viewer can be used to select which change(s) should be kept and in what order they should be if both are desired. If you do not want to resolve the conflict, click the Cancel button in the merge view and the pull will not take place.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_28.png"><img loading="lazy" class="alignnone size-medium wp-image-2250" alt="git_xcode_28" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_28-300x160.png" width="300" height="160" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_28-300x160.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_28.png 975w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>If the conflict is resolved, the working copy will be modified and will need to be committed and pushed.</p>
<p>To push changes to the remote repository, select File | Source Control | Push from the Xcode menu when viewing a project window.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_29.png"><img loading="lazy" class="alignnone size-medium wp-image-2251" alt="git_xcode_29" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_29-300x110.png" width="300" height="110" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_29-300x110.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_29.png 945w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>A branch can also be pushed to the remote repository.  Xcode will detect if the branch does not yet exist in the remote, and will indicate if the branch will be created by a push.</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_30.png"><img loading="lazy" class="alignnone size-medium wp-image-2252" alt="git_xcode_30" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_30-300x109.png" width="300" height="109" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_30-300x109.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_30.png 947w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Once a branch has been created on the remote repository, other working copies can track that branch.   To track a branch, visit Organizer, Repositories, and select Remotes for the project repository.  Expand the remote name to see the available branches.  (In my testing, I was not able to get Xcode to refresh remote branches without restarting Xcode).</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_31.png"><img loading="lazy" class="alignnone size-medium wp-image-2253" alt="git_xcode_31" src="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_31-300x74.png" width="300" height="74" srcset="https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_31-300x74.png 300w, https://www.cimgf.com/wp-content/uploads/2013/07/git_xcode_31.png 735w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Select a remote branch and click the Track Branch button at the bottom of the view.  This will pull down the branch from the remote repository to the local repository, will allow you to switch to the branch in Xcode, and will allow pulls and pushes to take place from it.</p>
<h2>SUMMARY</h2>
<p>As we have seen here, Xcode has very usable support for common Git tasks, including setting up Git for a new project, cloning an existing project, handling modifications and commits, viewing history, using branches, and pushing and pulling from remote repositories.  Xcode does not have direct support for stashing, tags, or more advanced topics like rebasing or submodules.  However, all of the items that Xcode does not support can be performed using the command line tools or using a third party tool.  In my day to day work with a distributed development team, I am frequently able to perform all of my Git tasks in Xcode, and only rarely need to resort to the command line.  Take a second look at Xcode’s Git support if you have not done so before, and give feedback to the Xcode team so they can keep enhancing and improving Git support in Xcode.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Creating A Happy Appy Song</title>
		<link>https://www.cimgf.com/2013/05/20/creating-a-happy-appy-song/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Mon, 20 May 2013 17:52:43 +0000</pubDate>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[Promotion]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2193</guid>

					<description><![CDATA[App developers need ways to promote their apps and audio and video provide a way to do that. At a recent iOS developer camp in Colorado I gave a talk in which I demonstrated some ways developers can create their own creative content like audio and video in-house. In one segment I demonstrated a technique [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>App developers need ways to promote their apps and audio and video provide a way to do that. At a recent iOS developer camp in Colorado I gave a talk in which I demonstrated some ways developers can create their own creative content like audio and video in-house. In one segment I demonstrated a technique that I refer to as creating a Happy Appy Song. What is it, you ask. You&#8217;ve heard it. It&#8217;s a happy sounding fanciful tune that plays in the background as some narrator describes the wonders and benefits of an app (or other product for that matter). The basic premise of the happy appy song is that, first of all, it&#8217;s easy to create, but second there&#8217;s a simple formula. Here is all you need:</p>
<p>1. A happy chord progression in a major key<br />
2. A simple drumbeat<br />
3. A glockenspiel sound</p>
<p>And now I present to you, Creating a Happy Appy Song</p>
<p>[ylwm_vimeo height=&#8221;400&#8243; width=&#8221;600&#8243;]66576979[/ylwm_vimeo]</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>iOS Crash Logs On iCloud Synced Devices</title>
		<link>https://www.cimgf.com/2013/04/26/ios-crash-logs-on-icloud-synced-devices/</link>
		
		<dc:creator><![CDATA[Matt Long]]></dc:creator>
		<pubDate>Fri, 26 Apr 2013 18:54:44 +0000</pubDate>
				<category><![CDATA[Beginner]]></category>
		<category><![CDATA[iOS]]></category>
		<guid isPermaLink="false">http://www.cimgf.com/?p=2181</guid>

					<description><![CDATA[I tweeted a call for help today to figure out how to get crash logs from a device that syncs with iCloud rather than with iTunes and a cable. The issue is that you can only sync with one and not both and switching between them willy nilly can be perilous unless you enjoy losing [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I tweeted a call for help today to figure out how to get crash logs from a device that syncs with iCloud rather than with iTunes and a cable. The issue is that you can only sync with one and not both and switching between them willy nilly can be perilous unless you enjoy losing your data just for the fun of it.</p>
<p>Several responses suggested taking things into my own hands by rolling my own logging mechanism when building an app I intend to ship. I think this is likely the approach I will take in the future, however, it doesn&#8217;t help my immediate problem. How do I get crash logs from an app I already shipped that is running on client&#8217;s device not physically located near me? Here&#8217;s a summary of what people suggested. Drill down in the settings app and copy the contents of the crash log like this (click/tap to enlarge):</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/04/CrashLogsDrillDown.png"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2013/04/CrashLogsDrillDown-300x76.png" alt="Crash Logs Drilldown" width="300" height="76" class="alignleft size-medium wp-image-2183" srcset="https://www.cimgf.com/wp-content/uploads/2013/04/CrashLogsDrillDown-300x76.png 300w, https://www.cimgf.com/wp-content/uploads/2013/04/CrashLogsDrillDown-1024x260.png 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Then, paste that into an email:</p>
<p><a href="https://www.cimgf.com/wp-content/uploads/2013/04/PasteInEmail.png"><img loading="lazy" src="https://www.cimgf.com/wp-content/uploads/2013/04/PasteInEmail-300x266.png" alt="Paste In Email" width="300" height="266" class="alignleft size-medium wp-image-2182" srcset="https://www.cimgf.com/wp-content/uploads/2013/04/PasteInEmail-300x266.png 300w, https://www.cimgf.com/wp-content/uploads/2013/04/PasteInEmail.png 823w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Then you can send the crash log to any email address you specify.</p>
<p>It certainly is not a pretty approach, but it will get the job done.</p>
<p>Thanks to the folks who responded to my call for help, <a href="https://twitter.com/davidiom">@davidiom</a>, <a href="https://twitter.com/therealkerni">@therealkerni</a>, <a href="https://twitter.com/thenighttrader">@thenighttrader</a>, and <a href="https://twitter.com/rckoenes">@rckoenes</a>. I appreciate it!</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
