Is Apple Using Swift in iOS?

Apple has been actively evangelizing the use of Swift since it was announced at WWDC in 2014. In the Platforms State of the Union, Andreas Wendker wrapped up the introduction to the new language, saying,

So, we are, as you can probably imagine, really, really excited about Swift. We think it’s quickly going to become the programming language of choice for our own code as well as your apps.

Swift has quickly gained popularity among many third party developers, but what about for Apple’s own code? As of iOS 9.2, Calculator.app is the only place in the system that you’ll find any Swift. I expected to find at least a few other apps or frameworks that had incrementally adopted Swift for new code, but that doesn’t appear to be the case for now.

Screenshot from the WWDC 2014 Platforms State of the Union

Calculator.app is actually almost “pure Swift” with only 2 of its 22 classes written in Objective-C. Just like third party apps that use Swift, Calculator.app has to bundle the Swift libraries it links to. There are no Swift libraries included with the OS because the ABI is not yet stable.

Apple also has a few apps that get distributed through the App Store rather than with the OS. What about those? In the same Platforms State of the Union talk that introduced Swift, it was announced that the WWDC app was updating to become the first public app to use the language:

… this afternoon, we’re updating the WWDC app, the app that you guys are using to get around here at the conference, with a version that uses Swift. So, this language is ready for you to use. It’s real.

While the WWDC app does in fact use Swift, it’s not as much as you might think. Out of 281 classes, only 6 are written in Swift. The Apple Store app is also using Swift for its watch app. That’s about all the production Swift I could find from Apple on iOS.

The choice to use Swift comes with some tradeoffs, and it appears that Apple has decided it’s generally not worth it for their apps or frameworks yet. However, there could be a very different story building for iOS 10. Since most of iOS is only dropped once per year, we’ll just have to wait and see in June.

WWDC quotes were taken from the excellent ASCIIwwdc.com


Update: Several people have noted that Dock on OS X has large portions written in Swift. To be clear, this post was focused on iOS and only investigated the frameworks and apps included in iOS 9.2. Apple’s Swift adoption in OS X could be significant, but I haven’t done the research.

Next Story — Building a Custom UIPageControl in Swift
Currently Reading - Building a Custom UIPageControl in Swift

Building a Custom UIPageControl in Swift

To help myself and our community establish good design patterns, I am trying to share my thought process every time I build something in Swift for the first time. In my current project, we need to build something similar to a UIPageControl, but with icons. It will control a UIScrollView and advance to a certain ‘page’ in the scroll view. My design goal is to use Enums to represent the different icons AND to hide the ObjC #selector() implementation details.

Here is my first take on this:

PageControl is a Class that basically wraps a UIStackView full of UIButtons. It inherits from NSObject because it acts as a target for the UIButtons.

The ViewCategory Enum represents the different type of pages and provides a convenient way to create a button with the appropriate image.

This is a pretty simple implementation and doesn’t address the possibility of custom layouts, different types of buttons, and probably 12 other things I’m not even thinking of. The UIStackView is publicly accessible, so spacing/distribution/alignment/axis could all be changed. Maybe it would make sense to pass in a config Struct in addition to the array of UIViews to configure the stack.

Let’s see it in action:

We now can easily just pass in Enum cases to configure our PageControl. It informs its delegate when a button is pressed and which index that button is.

Alright, what did I do wrong? What can I do better? Is there a better pattern for creating custom UI? Jesse Squires recently said that “using enums as configuration … is an anti-pattern” and I tend to agree, especially when building generic UI components. We could easily change this enum to accept a string property or use a ‘Configuration Model’ like Jesse uses.

Hit me up @iAmChrisTruman with opinions, criticism, trolling, and/or money.

Next Story — Using Third Party Framework in Playground with Carthage
Currently Reading - Using Third Party Framework in Playground with Carthage

Using Third Party Framework in Playground with Carthage

Now you can test them in Playground

nano Cartfile
  • Add any third party frameworks / dependencies in Cartfile. Here I’m adding Alamofire. *Don’t forget to check framework’s github, usually there is information about how to install that framework using Carthage.
github "Alamofire/Alamofire" ~> 3.0

If you’re using nano, press ctrl-x, press Y & enter to save changes.

  • Install the dependencies. If installation is successful, it will create Carthage folder with two subfolder, Build and Checkouts.
carthage update --platform iOS

If you want to know how to use this dependencies in your iOS project, you can read the full tutorial here. Now, let’s use this dependencies in our Playground.

  • Create new Playground. In your project folder, choose File ‣ New ‣ File… and choose Source ‣ Playground.
  • Save your project as workspace. Choose File ‣ Save As Workspace…
  • Close your project and open workspace file you’ve just created (*.xcworkspace).
  • Right click on your project folder and choose Add Files to “Your_Project”…
  • Choose dependency’s project file. Here, I’m choosing Alamofire.xcodeproj in Carthage/Checkouts/Alamofire/Alamofire.xcodeproj
  • Clean project to make clean any last build. Product ‣ Clean.
  • Build project. Product ‣ Build.
  • Open your Playground and now you can import the framework.

Tips for using Alamofire (and other framework that run Asynchronously) in Playground.

  • import XCPlayground and set execution to run indefinitely.
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
  • Add this before any code and this will make XCode to run Playground code forever rather than just one time run and stop. So any async code can be inspected.
  • After async code execution, you can stop Playground’s indefinite execution.
XCPlaygroundPage.currentPage.needsIndefiniteExecution = false
Next Story — CocoaPods vs. Carthage
Currently Reading - CocoaPods vs. Carthage

CocoaPods vs. Carthage

I’ve been dealing a lot with both CocoaPods and Carthage lately and I would like to share my thoughts about both of them.

3rd Party Frameworks are a big deal in both iOS and OS X development. There’s a ton of ready to use libraries on Github and most of them can be added to your project using either Carthage or CocoaPods (You could also add them manually as a submodule, but I like the ability to just add them via aforementioned dependency managers).
CocoaPods is here since the early days, when iOS Apps still have been written in Objective-C only. It’s pretty easy to add a library to your project. Just create a text file in the root folder of you application named ‘Podfile’ and add ‘pod “FrameworkName”’ (where FrameworkName has to be replaced with the actual name of the framework) to the file. Run ‘pod install’ in Terminal and CocoaPods does the rest for you. After that you’ll have to open your projects via a .xcworkspace file in your app’s root folder which has all the pods in it you just added, ready to use.
Carthage does a similar job. You add a text file named ‘Cartfile’ to your app’s root folder and add ‘github “FrameworkName”’. After that run a simple ‘carthage update’ in Terminal and carthage adds and builds the libraries. After that you’ll find a folder named Carthage in your app’s root folder. In that folder there’s a ‘Build’ folder from where you have to drag the frameworks you want to use into the “Linked Frameworks and Libraries” section in Xcode. So, with that here are the differences:
First of all the setup. To set up CocoaPods for your machine, you have to run ‘sudo gem install cocoapods’ in Terminal. This adds all necessary gems required to install pods. For Carthage there are two ways: Either you run ‘brew install carthage’ when you’ve got Homebrew installed, or you download the .pkg from https://github.com/Carthage/Carthage/releases and install it manually.
Next is usage. While CocoaPods is pretty easy to use, Carthage is more flexible. CocoaPods creates a .xcworkspace file in which all your pods are listed. This makes it easier to use, but also less error proof. If one library fails to build, your whole project doesn’t work. In Carthage you have to add the frameworks you really want to use into your project manually. This means you have to do some extra work, but it also adds a lot more flexibility. Also if you want to get rid off Carthage, you just have to delete the Cartfile and Cartfile.resolved files and the Carthage folder. I couldn’t find such an elegant solution for CocoaPods. First of all you have to delete the .xcworkspace, the Podfile and Podfile.lock files, the Pods folder and a bunch of other stuff inside Xcode.
The only downside I found about Carthage is that not all frameworks are available for Carthage. Especially older frameworks aren’t available for Carthage, and if you don’t want to use CocoaPods for them you have to add those manually. Just run terminal and run ‘git submodule add (link to framework)’.

Conclusion
Whatever dependency manager you search for, both CocoaPods and Carthage do a pretty good job. If you want something easy to use, which has been there for years, take CocoaPods. If you want a fresh approach, which is almost completely written in Swift and gives you more flexibility, go for Carthage. It already works great and over time more authors will support Carthage.
I hope I could help a little with making a choice between two great tools, that are designed to make our lives better.

Next Story — How I Deleted 10k Lines of Code & Turned 2 Minutes into 1 Second
Currently Reading - How I Deleted 10k Lines of Code & Turned 2 Minutes into 1 Second

How I Deleted 10k Lines of Code & Turned 2 Minutes into 1 Second

A Core Data Story

It’s been a not-too-uncommon rhetoric that Core Data is slow, buggy, or needlessly complex. I’ll be the first to admit that it’s not a perfect framework. However, far too often it is used as a scapegoat for whatever issues a developer is facing. Core Data is complex, but data management is complex. Attempts to simplify it don’t scale. With a little bit more effort, Core Data does scale.

Core Data has made great strides in recent years, with additions such as batch updates and deletions, asynchronous fetches, unique constraints, etc. I highly recommend the What’s New in Core Data talks at every WWDC.

Case Study

My first task at my previous job was to turn the prototype app into a “ready for App Store” product. But there was a problem. After using the app daily for a few months, the founder had accrued lots of data. Logging in from a fresh install took over 2 minutes to fully synchronize. Users get impatient even with 2 seconds; this took over 120 grueling seconds.

After a bit of investigation, it turned out that all data synchronization, from the HTTP requests, to response parsing and saving in Core Data, was handled by a single framework.

I ended up replacing the library with AFNetworking for HTTP requests and custom code for the Core Data layer. How long did it take to login and sync? Less than 1 second.

Success! 100x improvement! Why the huge difference? To understand how I was able to get such a huge speedup, let’s look at what each approach was doing.

Library’s Approach

  1. Parse each object, one at a time, from the JSON response
  2. Run a fetch request to see if this object exists
  3. Create or update
  4. Save
  5. Repeat from step 2 until done

For each object, we were doing a fetch, create/update and save. As our dataset grew to hundreds and thousands, we were executing an increasing amount of fetches.

Custom Code

  1. Parse out all Object IDs from the JSON response
  2. Run 1 batch request to fetch all our needed objects
  3. Create a dictionary of [Object ID: Core Data object]
  4. Iterate through the JSON response. For each object, grab the pre-fetched object from our dictionary, then create or update.
  5. Save

Now we’re only executing 1 fetch for all objects, then a create/update per object, and a final save at the end. As our dataset grew, we were still only executing 1 fetch.

Sure, this is easier said than done. To get away with batch fetching our objects ahead of time, we have to ensure that mapping operations do not execute in parallel. This prevents, for example, 2 separate operations receiving data about object ABC123, not finding it, and therefore creating it. To enforce this, we ensure all data mapping occurs on a serial NSOperationQueue.

The payoffs were enormous. Since we knew exactly how our data was structured, and how our mapping operations took place, we were able to make assumptions and custom tailor our code to be as optimized as possible. As an added bonus, the entire team team gained insight into what our code was doing and got to learn how to use Core Data directly. New hires that came on later didn’t have to learn a new library, since they already knew Core Data.

The Moral of the Story

I’m not claiming that 3rd party libraries are bad and should be avoided. There is a lot of great work in the Cocoa open source community, and nearly all of my apps use at least one project from GitHub. I’m just recommending that you should understand what the library is doing or what it is replacing.

As a rule of thumb, I’d recommend not using a generic 3rd party library until you have tried Cocoa’s alternative. I don’t mean go implement your own QR code scanner or image processing library. Rather, before you jump into something like AFNetworking/AlamoFire (which is a great library that I sometimes still use), try writing some requests with NSURLSession.

Bonus — Swift!

This application was written entirely in Objective-C. However, since a lot of the data mapping operation involved transforming data from JSON to dictionaries, I was curious if the Swift compiler would yield further improvements

Swift 1 performed slightly slower than Objective-C. Swift 2.0 performed just as fast as Obj-C. However, the Swift code took a sizeable performance penalty from bridging between Obj-C and Swift. I haven’t tried this test with newer versions of Swift, but I’d be willing to bet it would be faster!


Thank you for reading! If you like this article, please take a moment to click the Share or Recommend button so more people will be able to read it.

To read more of my writing, check out my other story.

Lastly, you can follow me on Twitter, where I talk alot about iOS design & development.

Sign up to continue reading what matters most to you

Great stories deserve a great audience

Continue reading