mhayes – The uShip Blog https://ushipblogsubd.wpengine.com Tue, 15 Jul 2025 19:45:43 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.2 Streamlined, Manual JSON Parsing in Swift https://ushipblogsubd.wpengine.com/shipping-code/streamlined-manual-json-parsing-swift/ https://ushipblogsubd.wpengine.com/shipping-code/streamlined-manual-json-parsing-swift/#comments Mon, 26 Sep 2016 15:53:52 +0000 https://ushipblogsubd.wpengine.com/?p=6424 There’s plenty of articles out there about how to parse JSON in Swift, what libraries to use.  Apple even posted one themselves as I was finishing up this post.  What I’d like to talk about here is the way the uShip iOS app handles JSON parsing, which is a variation of Apple’s approach. Sharing maintainable Swift code is... Read More

The post Streamlined, Manual JSON Parsing in Swift appeared first on The uShip Blog.

]]>
There’s plenty of articles out there about how to parse JSON in Swift, what libraries to use.  Apple even posted one themselves as I was finishing up this post.  What I’d like to talk about here is the way the uShip iOS app handles JSON parsing, which is a variation of Apple’s approach.

Sharing maintainable Swift code is a Challenge

Since its introduction just over two years ago, Apple’s Swift programming language has shown itself to be a language that can be really fun to work with.   uShip’s iOS team chose to adopt the language very early on and in the process has had to learn to deal with some interesting challenges as a result.

One particular challenge comes with adopting 3rd party libraries.  If you’re working with Swift, one thing to consider in adopting a library is how frequently such libraries are kept up to date.  It’s important to consider how bad it may be if these libraries stop compiling when you have to move on to a new version of XCode.  And unlike some other development environments, it is extremely challenging to produce and distribute reusable pre-compiled libraries.  Instead it is common for shared code modules to be distributed as source code for others to compile themselves.  Even if you use cocoapods, you’re still having to compile the pods yourself.  Another dependency management system, Carthage, claims to support shared binary libraries, but until very recently this was only true if you were sharing the binaries with yourself on a single machine.  This all becomes a pretty big issue when the actual source code language is changing drastically over time.

With all this in mind, sometimes it can be a big timesaver to replace a third-party library we’re using with simpler, in-house code that we can easily maintain ourselves.  One place we’ve chosen to do this is in parsing JSON.

The iOS SDK doesn’t parse JSON for you

One thing that may surprise developers from other languages is that there’s no built-in way to instantly parse JSON objects into Data Transfer Objects (strongly typed data structures).  There ARE some third party libraries out there for doing this:  SwiftyJSON, and dankogai’s swift-json, among others.  But as mentioned above, if you’re trying to avoid depending on 3rd party code, it’s worth considering doing it yourself.

As it turns out JSON parsing is not such a bad candidate for a more manual approach.  Throughout the rest of this article, I’ll be sharing with you the technique we use in the uShip app for taking raw JSON data and converting it into strongly typed, Swift structs.  These structs clearly expose the structure and meaning of data from a given endpoint.  They are also easily composable and reusable with other similar endpoints, and can even help you build in sensible default values for missing values in a structure.
How we set up our Swift JSON parsing
Let’s step through the approach the uShip app is currently using.

Create A DTO Protocol

The first major piece of the puzzle was in creating a special protocol for all of our DTOs (Data Transfer Objects) to adopt, which simply specifies that these DTOs must have a constructor that allows them to be built with one of the basic JSON data types (Dictionary, Array, String, Number or Bool).  At uShip all of our APIs provide NSDictionary or NSArray objects, so we’ll focus on those.
public enum JSONType {

case array(array:[AnyObject])
case dictionary(dictionary:[String:AnyObject])

//…

public static func create(jsonObject: AnyObject?) -> JSONType {

//…

}
}

public protocol JSONObjectConvertable {
init?(JSON: JSONType?)
}
Create Collection Extensions
The second part was in creating a set of extensions on the Swift Dictionary and Array types.  These extensions have a set of functions which accept a key value or index into the collection object and return the strongly-typed value associated with that key or index.  Through the power of Swift Generics, we’re able to give all of these functions the same exact name.  Because of this, all you need to know in order to use these functions is that one function name.  We also created one additional override of this function which could grab the collection value and return it as a type conforming to our JSON data protocol (described in the last paragraph).  For example:
public extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject
{
//looks for a value with the given key
//if the value exists with the expected type, returns the value as that type
//returns nil otherwise
public func jsonValue<T>(_ key: String) -> T?
{
return (self[key as! Key] as? T)
}

//…

}
If you’re unused to Swift generics that code may be a little difficult to wrap your head around. The function  jsonValue<T>(key:) works based on what you assign its return value to.  If you assign the result to a string, it will return the dictionary value if it happens to actually be a string.  If it isn’t a string, it will return nil.  If you instead assign it to an NSNumber, it will only return the value if it is actually an NSNumber.   If we want to pull out values of a non-object, primitive type like Float or UInt, we need more specialized overrides of this function.
public func jsonValue(_ key: String) -> Float?
{
return (self[key as! Key] as? NSNumber)?.floatValue
}

public func jsonValue(_ key: String) -> UInt?
{
return (self[key as! Key] as? NSNumber)?.uintValue
}
Create DTO Types
Finally we combine the first two pieces within a concrete DTO designed to mirror the expected contents of a JSON object.  We do this by creating a struct, having it conform to our DTO Protocol, and then in the protocol-required constructor, we use our collection extensions to parse whatever data is passed in by the arguments.
struct User : JSONObjectConvertable {

var id : UInt?
var username : String?

init?(JSON: JSONObject?) {

guard let json = json else { return nil }
guard case .dictionary(let dictionary) = JSON else { return nil }

id = dictionary.jsonValue(“id”)
username = dictionary.jsonValue(“username”)

}
}
 

This shows everything really coming together.  Our User DTO adopts the custom JSONObjectConvertable protocol, so it must have the two required initializers.  In the second initializer, we ensure that the JSON object we build from is of the expected dictionary type.  And finally we populate the “id” and “username” properties with our jsonValue extension function.  Each call to jsonValue calls a different version of the function because we have one version that handles String optionals and one that handles UInt optionals.
Use the DTOs
Once this DTO is set up, we can put it to use wherever we get data back from a JSON document.  Below we get data from an API endpoint and parse it using one of our DTO types:
let JSONObject = try? JSONSerialization.jsonObject(with: data, options:[])
let JSON = JSONType.create(jsonObject: JSONObject)
That’s it.  And after you set up one endpoint, adding DTOs for more endpoints becomes increasingly easier.  Most of the work is done by the collection extensions, which are reusable.  Our actual networking code is a bit more complex than that, but explaining that is outside the scope of this particular article.

For more details on the code, check out our sample project, which uses this technique to parse JSON Data from NASA’s API for downloading photos from the Curiosity Mars Rover.

And if you want to try running the project for yourself, you might even see some cool martian landscapes!

Or Mars rover selfies.

The post Streamlined, Manual JSON Parsing in Swift appeared first on The uShip Blog.

]]>
https://ushipblogsubd.wpengine.com/shipping-code/streamlined-manual-json-parsing-swift/feed/ 1
IdeaFlow for iOS https://ushipblogsubd.wpengine.com/shipping-code/ideaflow-for-ios/ https://ushipblogsubd.wpengine.com/shipping-code/ideaflow-for-ios/#respond Thu, 05 Nov 2015 15:56:30 +0000 https://ushipblogsubd.wpengine.com/?p=4217 A couple months back, one of my fellow uShip developers popped his head into my team’s room at the end of the day.  “You guys going to the API meetup?”, he asked.  As an iOS developer, I don’t actually write APIs very often, but I’m interested enough in how consumable they are.  Why not go?... Read More

The post IdeaFlow for iOS appeared first on The uShip Blog.

]]>
A couple months back, one of my fellow uShip developers popped his head into my team’s room at the end of the day.  “You guys going to the API meetup?”, he asked.  As an iOS developer, I don’t actually write APIs very often, but I’m interested enough in how consumable they are.  Why not go?  Soon enough we were all walking up to Capital Factory where Austin Homegrown API was set to present a talk entitled “An Open Standard for Learnable APIs”.  I didn’t know what that meant, but it seemed like it could be interesting.

 

This talk was based on some research by a Janelle Klein of New Iron.  The research was the basis for a book she was working on.  It just so happened her research was centered around exactly the part of APIs I care about.  She just put it differently.  Rather than ask how consumable a given API is.  She asked the question, how painful is it for a developer to work with that API?  She also presented a way to actually measure that quantitatively.  Having this sort of raw data makes for great feedback for API developers.

 

What really grabbed my attention was the actual tool Ms. Klein was using to gather data.  It was actually pretty simple.  Just an IDE widget where you can select what sort of work you’re doing at the moment:  Learning, Troubleshooting, Rework, or just regular productive time.  The tool logs enough data that you can produce a timeline of these events for your project, allowing you to easily see if you’re spending way too much time doing less than productive work.   

 

I came away from this presentation pretty inspired.  We’re beginning to write more iOS code libraries at uShip and we care a great deal about making sure they’re easy for our fellow developers to use.  So I wanted to try this tracking tool and see what data I could get on some of these libraries.  However Janelle’s tool happened to be written for Java developers who use Eclipse.  Eclipse isn’t really an option for iOS developers.  Hmm… how could I track data like this without working in Eclipse?  Why not make an app for that?

 

It just so happens that uShip had an hackathon event coming up.  Some of our web developers were eager to try their hand at developing something on iOS so I pitched IdeaFlow as something we could build together.   We ended up with a working prototype app for tracking IdeaFlow data on an iPhone.  

 

You can check out the now open-sourced app here.  

 

The post IdeaFlow for iOS appeared first on The uShip Blog.

]]>
https://ushipblogsubd.wpengine.com/shipping-code/ideaflow-for-ios/feed/ 0
Unit Testing Around Singletons with OCMock https://ushipblogsubd.wpengine.com/shipping-code/unit-testing-around-singletons-with-ocmock/ https://ushipblogsubd.wpengine.com/shipping-code/unit-testing-around-singletons-with-ocmock/#respond Thu, 20 Feb 2014 15:58:14 +0000 http://ushipblogsubd.wpengine.com/?p=3467 Whether you agree with the use of singletons or not, you can’t completely avoid them as an iOS developer. Apple provides some critical functionality through singletons exposed in its iOS SDK, but it can be quite difficult to write unit tests around code that accesses them. In this article, I will describe a couple of... Read More

The post Unit Testing Around Singletons with OCMock appeared first on The uShip Blog.

]]>
Whether you agree with the use of singletons or not, you can’t completely avoid them as an iOS developer. Apple provides some critical functionality through singletons exposed in its iOS SDK, but it can be quite difficult to write unit tests around code that accesses them. In this article, I will describe a couple of techniques for managing this. First though, let’s set up an example of the sort of problem I’m talking about.

Problem

Let’s say we have an app which is set up to register itself for push notifications. We’ve already written a simple proof-of-concept view controller with a switch for the user to enable or disable these notifications. The code is written and working well, but looks terrible.

 

I mean how is the user supposed to know what that switch does?  And is it bugging anyone else that the switch isn’t even centered? Clearly, we should make this screen a bit more interesting and add some new features. Maybe a label… some more colors…oh! how about some animation?

Whatever we decide to do, we want to make sure we don’t break the existing functionality.  The switch works, but there are no unit tests to verify that it does.

Solution

While our designer figures out what features we want to add, let’s give this code some test coverage.  Let’s start by taking a look at the code we’re going to work with.  Here is the interface for the view controller.

[cc lang=”objc”]
@interface SettingsViewController : UIViewController
{
@property (nonatomic, strong) IBOutlet UISwitch *pushNotificationsSwitch;
– (IBAction)pushNotificationsSwitchWasToggled:(id)sender;
}
[/cc]

…and here’s the implementation.

[cc lang=”objc”]
@implementation SettingsViewController

– (void)viewDidLoad
{
//create the switch
self.pushNotificationsSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 50, 30)];

//link it to the action method
[self.pushNotificationsSwitch addTarget:self action:@selector(pushNotificationsSwitchWasToggled:) forControlEvents:UIControlEventValueChanged];
}

– (IBAction)pushNotificationsSwitchWasToggled:(id)sender
{
UISwitch *toggleSwitch = sender;
if (toggleSwitch.on)
{
//if the switch was toggled on, register for push notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];
}
else
{
//if it was toggled off, unregister
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
}
}
@end
[/cc]

We’ll first try to write a test to verify that the app gets registered for push notifications when that lonely switch gets flipped to ON.

[cc lang=”objc”]
– (void)testToggleOnRegistersForPushNotifications_On
{
//given the view controller is loaded
SettingsViewController *sut = [[SettingsViewController alloc] init];
[sut view];

//given the switch is toggled on
[sut.pushNotificationsSwitch setOn:YES];

//when the view controller is notified that the switch was toggled
[sut pushNotificationsSwitchWasToggled:sut.pushNotificationsSwitch];

//then the app should register for notifications with alerts and badges
//?? how do we verify this
}
[/cc]

Let’s walk through what’s going on here.  We create an instance of the SUT, then simulate the act of flipping the switch to ON. Unfortunately, we’re not sure now how to verify that the switch did what it’s supposed to because all it does is call methods on the UIApplication singleton! To finish the test, we need to figure out a way to expose [UIApplication sharedApplication] as a dependency. One way to do that is through dependency injection.

With Dependency Injection

To use dependency injection, we’ll have to modify our view controller class so we can provide an instance of UIApplication that it can work with. Then the app can use the real sharedApplication instance, while the test uses a mock object.  To accomplish this, we’ll add a new property to the SettingsViewController interface…

[cc lang=”objc”]
@property (nonatomic, strong) UIApplication *application;
[/cc]

…and modify our view controller implementation to use it.

[cc lang=”objc”]
– (UIApplication*)application
{
if (!_application)
{
_application = [UIApplication sharedApplication];
}
return _application;
}

– (IBAction)pushNotificationsSwitchWasToggled:(id)sender
{
UISwitch *toggleSwitch = sender;
if (toggleSwitch.on)
{
[self.application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];
}
else
{
[self.application unregisterForRemoteNotifications];
[/cc]

The first method here is lazy-loading the application property so that it defaults to [UIApplication sharedApplication] when the app is running for real.  Then we changed pushNotificationsSwitchWasToggled: to refer to self.application instead of [UIApplication sharedApplication].

With that out of the way, we can finish our test by initializing the view controller with a mock object before the switch is toggled. The test can then monitor that mock to verify the behavior we’re expecting. Here’s our unit test again. This time, the test is using the mocking framework OCMock to create the mock, set up expectations, and verify them.

[cc lang=”objc”]
– (void)testToggleOnRegistersForPushNotifications_On
{
//given
id mockApplication = [OCMockObject niceMockForClass:[UIApplication class]];
[[mockApplication expect] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];

SettingsViewController *sut = [[SettingsViewController alloc] init];
sut.application = mockApplication;
[sut view];
[sut.pushNotificationsSwitch setOn:YES];

//when
[sut pushNotificationsSwitchWasToggled:sut.pushNotificationsSwitch];

//then
[mockApplication verify];
}
[/cc]

Here our mock instance is configured to expect a message with the signature registerForRemoteNotificationTypes: and some very specific arguments. We then simulate flipping the switch to ON. At the end of the test, we ask the mock to verify that the expected method was actually called. If not, the test raises an exception on that last line and the test is reported as a failure.

You’ll notice that to use dependency injection, we had to modify a lot of our app’s code to make it testable.  Imagine SettingsViewController was a much larger and more complicated class without any unit test coverage. It could be quite intimidating to have to change that code just to make it testable. You could break it just trying to test it. If for some reason you can’t or don’t want to take that risk, there’s another way to test this code.

Without Dependency Injection

In the case of our SettingsViewController, we can actually stub out this singleton dependency without resorting to dependency injection. OCMock in particular is actually quite helpful in this case. With the help of OCMock, we can temporarily replace the singleton instance with a mock object that can be monitored by our test.

Here’s that same test again, but this time, we’ll do our mocking without dependency injection.

[cc lang=”objc”]
– (void)testToggleOnRegistersForPushNotifications_On
{
//given a mock UIApplication
id mockApplication = [OCMockObject niceMockForClass:[UIApplication class]];
[[[mockApplication stub] andReturn:mockApplication] sharedApplication];
[[mockApplication expect] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];

//given the view controller is loaded
SettingsViewController *sut = [[SettingsViewController alloc] init];
[sut view];

//given the switch is toggled on
[sut.pushNotificationsSwitch setOn:YES];

//when the view controller is notified that the switch was toggled
[sut pushNotificationsSwitchWasToggled:sut.pushNotificationsSwitch];

//then the app should register for notifications with alerts and badges
[mockApplication verify];

//finally clean up the mock (VERY IMPORTANT)
[mockApplication stopMocking];
}
[/cc]

Here we simply stub out the singleton accessor method and force it to return our mock object. Now, whenever any code in the app calls [UIApplication sharedApplication], it will actually get this instance of OCMockObject instead.

You may have noticed that the first time we wrote this test we didn’t call stopMocking at the end. Normally, at the end of a test, you don’t have to worry about cleaning up a mock instance like this. A normal mock just evaporates as soon as it falls out of scope. But not this one. Since we’re mocking a singleton, the instance won’t actually fall out of scope after the test.

Try this to see what I mean. Comment out the stopMocking line in the test above and add this test at the end of the same test suite:

[cc lang=”objc”]
– (void)testZ_MockWasActuallyDestroyed
{
id app = [UIApplication sharedApplication];
XCTAssert([app isMemberOfClass:[UIApplication class]],
@”a mock for UIApplication sharedApplication was not cleaned up!”);
}
[/cc]

The ‘Z’ at the front of the test name just forces it to run last. This is because OCUnit/XCUnit tests run in alphabetical order.  With the call to stopMocking commented out, you’ll see that this new test fails.

So it’s VERY IMPORTANT that you call OCMock’s stopMocking method on the mock singleton object when you’re done with it. Forgetting this step means your mock singleton instance will survive and potentially influence the outcome of other unit tests.

You can find a sample project on github which shows all the code above in action.  It also includes some alternate unit tests which demonstrate doing some of the same things using Jon Reid’s OCMockito, instead of OCMock.

[amp-cta id=’8486′]

The post Unit Testing Around Singletons with OCMock appeared first on The uShip Blog.

]]>
https://ushipblogsubd.wpengine.com/shipping-code/unit-testing-around-singletons-with-ocmock/feed/ 0