New York Mobile Forum (30 Nov 2014)

This the first ‘Mobile forum’ event I’ve seen in New york. Invite only and held at the facebook office at Astor place. The format was based around small groups brainstorming and open discussion, then group facilitators would present key points to all attendees.

here are the top take aways I had:

You should try out Slack for internal communications

I heard Slack recommended throughout discussion. Especially its search functions. I actually haven’t had the chance to use it, but am now very keen.

Train web developers into native

Mobile teams need more developers than the market can handle, and web is becoming a secondary platform to native. Etsy spoke about having dedicated roles for training into the native space. Identify developers who are keen to make the transition and give them full support.

Build a testing culture, but tread lightly

The tools are still in infacy to support native TDD, and they probably will never get to a level when testing can be fully embraced. Culture spawned from the web world (where testing is simpler) have transitoned and can adversely impact delivery if taken at full speed.

Modularise code bases into libraries

Modular code is a given, but splitting your app into libraries takes an extra level of foresight. The tools are not great, and you will incur overhead costs, but some time in the future you will need to draw a line in the sand and split your architecture out.

Force yourself to have 1-on-1’s

Giving and receiving feedback is not natural, but without it teams and the individuals will have trouble growing. The 1-on-1 gives a unique opportunity to get a certain level of honesty. It keeps you accountable and gets feelings out in the open. Especially important in remote teams, but I would recommend regular 1-on-1’s in all dev teams.

Pull based API schemas

Facebook’s mobile app pulls lots of data, and with large teams and large data needs they experienced overfetching (too much data coming back, makes managing responses sluggish) and underfetching (where the API data does not match the needs of the client so additional round trips are needed). As far as I understood it, A pull based API means that:

  • You have only 1 endpoint
  • The client specifies an entity schema and gets back a token. e.g:
1
2
POST /api/schema_register
{newsfeed{date,title,author{friends}},messages,...}
  • The token is then stored on the client, and used to request the exact data it needs for all future requests
  • The API never deletes fields, or has relaxed deprecation
  • The API only sends back what is requested. This addresses over/under fetching problems
  • A GET request may look like:
1
2
3
GET /api/data?schema_token=1234
RESPONSE:
{ "newsfeed" : { "date" : "1414960696", "title" : "foo" ...

At Meetup this problem existed as well. We were requesting additional fields all the time. Scaling the schema identifiers may cause problems but overall i like this approach

The format

Really liked the peer-to-peer discussions. I was having conversations about identical problems others had faced and insights into their unique solutions. I’d like to see some more controversial, ‘out of the box’ topics next time. And maybe splitting platform specific discussions to their respective audience (I was not too interested in Android JVM issues presentation).

Core Data

If you’re an iOS developer you probably use Core data every day. I have been learning Core data for the last year professionally, and in my spare time for use in my own apps. I thought I would post some tips that maybe helpful in getting your head around this useful but difficult Apple framework.

Entities and Context

The NSManagedObjectContext is one of the most important classes to understand. Apple calls this the scratch pad, another way to think of it is the reference to the your entities world

The general definition of a World is:

  • a group of living things.
  • a period of history.
  • all of the people, societies, and institutions on the earth.

When first learning Core Data the context can be annoying, why cant I can just make changes to objects and make them stick? But if you think if it in terms of the world in which things happen, it makes more sense.

Every data change event that happens must be tied to a context, and context’s can never be traversed (although they can be merged). The NSManagedObjectContext is your world according to core data and you should structure your code to always have access to it and make changes in reference to it.

Continuing on with the analogy, a living thing is your NSManagedObject. In the context of its world, changes can happen to the living objects, they can be created and deleted. The world itself can even be deleted, which is handy for discarding edits.

Threading

Introducing threading can dramatically change the structure of your application without a safetey net, so extra caution should be taken. Debugging often becomes more difficult also. In core data the NSManagedObjectContext can be tied to the main thread, or any thread during creation. If tied to the main thread your operations have the potention to cause app to freeze while in progress. In that case we need to explore threading.

Core data provides the method - (void)performBlock:(void (^)())block on NSManagedObjectContext as a compact wrapper around operations that can be performed on any thread. But the simplicity of this method is deceiving.

Threaded notifications

If you watch NSNotifications from NSManagedObjectContext for changes in data, you now have to be aware of the thread they are received on. Code that makes changes to your UI such as UIKit must be on the main thread. If you make changes in core data background threads these notifications can appear from those threads and cause UIKit to crash that are almost impossible to trace back.

I have shipped code which actually made this mistake, so have built in protection against it

Use child/parent NSManagedObjectContext to make your changes and submit them back to a parent which you know is tied to the main thread. More on this NSPrivateQueueConcurrencyType

Thread contention & atomic operations

You should confine all core data performBlock’s to the one serial NSOperationQueue for safety.

When a performBlock makes changes to data, there’s no guaratee another performBlock is not performing changes on a different thread at approximately the same time. When this happens you run the risk of core data returning errors that make no sense. Enqueueing core data operations into a serial NSOperationQueue will guard against this. I’ve added a short gist to show an example

Migrations

Objc.io has a nice writeup on the subject. After skimming through it you may come to this conclusion which I strongly recommend: Avoid non light-weight migrations.

This is totally possible if you are a bit creative, and its worth the extra effort. These are my reccommendations:

If a properties data type changes, create a new property instead of modifying the existing one

Changing the datatype will not allow light-weight migrations to happen. This is because CoreData doesn’t know how to modify the existing data to conform to the new datatype. If you create a new property and delete the old one, If you care about keeping the old data you have no choice but to venture into manual migration territory.

Use 2 managed object models

If you have data that you need to keep persistent accross app deployments then it maybe worth keep that in a different datamodel (or outside Core Data). One where migrations are important. Data that is purely an offline cache can be kept separate where migrations are not even considered, the data is killed each new app update.

Use magical record for the right reasons

Magical record is an abstraction layer ontop of Core Data. I use it for my own apps, but still know how to drop down to the level of pure Core Data. There’s many resources for learning more, Apple has an write up of its own which maybe a good place to start

Core Data is worth the headaches

I think its a given that every iOS dev wrestles with Core Data during the course of their career, but as a persistence layer it does a pretty great job of managing many of needs of modern iOS apps.

Pretty good

Girl Develop-it

This week I helped with and iOS programming class for Girl developit meetup, hosted by Joe Burgess. The format was little to no pre-requisite programming skill, so the students were writing their first for loops and if statements.

Objective-C is a difficult first programming language, so one thing Joe said in the class stuck with me, that was:

it’s not that anyone is smarter than you are, it’s just they’ve been doing it longer.

He said this a couple of times throughout the lesson and the exercises. I think its a great thing to ground yourself. When something seems un-attainable to grasp in your understanding, it just takes additional time.

Many problems in code come down to your mental model not fitting to whats happening. So you need to debug the code, and adjust your understanding. For that breif period you feel stupid, but it also can be a fun challenge. That is coding.

Xcode Shortcuts

Ctrl + Cmd + J Jump to definition (under the cursor)

Ctrl + 1 Show related items, from here you can select super classes or recent files

shortcut 2

Ctrl + 6 Show document items (methods outlines). Start typing to filter

shortcut 2

Ctrl + a Move cursor to start of line Ctrl + e Move cursor to end of line

Some more well known:

Cmd + Shift + j Highlight current file in group folder view

Cmd + Shift + o Open quickly

Ctrl + Cmd + Navigate back a file

Ctrl + Cmd + Navigate forward a file

Unit Testing Block Based Callbacks

I recently tackled unit testing my AFNetworking client classes, which use block based callbacks, stubbing out block callbacks took some trial and error so is worth of a blogpost.

Take the example method:

1
2
- (AFHTTPRequestOperation*)meWithSuccess:(void (^)(AFHTTPRequestOperation *operation, NSDictionary *responseObject))success
                                 failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure

How would you go about mocking/stubbing this method call? One way is to use OCMock expectations. In your unit test setUp:

1
2
3
4
5
6
7
8
9
10
11
12
13
self.stubMessagesPayload = @{
     @"has_mail" : @0,
     @"has_mod_mail" : @0,
};

_client = [OCMockObject mockForClass:[AFRedditAPIClient class]];

[[[_client expect] andDo:^(NSInvocation *invocation) {
    void (^__unsafe_unretained successStub)(AFHTTPRequestOperation *, NSDictionary *);
    [invocation getArgument:(&successStub) atIndex:2];
    
    successStub(nil,self.stubMessagesPayload);
}] meWithSuccess:[OCMArg any] failure:[OCMArg any]];    

In the actual test, you can change the value of stubMessagesPayload and assert different behaviour. You’ll also notice the block argument is located at index 2, from the documentation:

Indices 0 and 1 indicate the hidden arguments self and _cmd, respectively; these values can be retrieved directly with the target and selector methods. Use indices 2 and greater for the arguments normally passed in a message.

The other issue you may face is how to get your class to actually use the mocked version of your object. The code under test may look like this:

1
2
3
4
5
[[AFRedditAPIClient sharedClient] meWithSuccess:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
NSLog(@"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"failure");
}];

The only way to stub a class method is via swizzling, which can get messy. The alternative is dependency injection, whereby you expose object dependencies using properties or constructor varaibles. Then they can be swapped more easily at runtime, so if the AFRedditAPIClient object where a public property, and RCMessageClient were the class i wanted to test, expose the dependency using a property and in the test asign it to the mock object:

1
2
3
4
5
6
_apiClient = [OCMockObject mockForClass:[AFRedditAPIClient class]];
_messageClient = [[RCMessageClient alloc] init];
_messageClient.apiClient = _apiClient
...
Additional stubs explained above
...

And the implementation changes to refer to that property instead of the class method:

1
2
3
4
5
[_apiClient meWithSuccess:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
NSLog(@"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"failure");
}];

E3 Visa Expedition

This post is about a recent US tour I took with the goal of finding work as an iOS Developer in New York. In March of this year I made the decision to quit my job and take the plunge. I was solo, and planned accommodation only 1-2 weeks in advance, so had a huge amount of flexibility.

Another factor for the timing was the WWDC conference. I didn’t get a ticket the amount of side events and altWWDC made it more than worth it.

I was there for 4 months, did a lot of of sight seeing also, but we’ll skip over that.

Getting around

I was ‘on the cheap’ so flew Jetstar Melbourne > Honolulu ($700) then Honolulu > Vancouver ($220). Once on the mainland the Megabus and Greyhound were the preferred mode of transport. Both cheap and allow for great flexibility, the clientele can be pretty rough though.

Looking online

I stayed away from traditional job seek sites, the amount of recruiter spam seemed massive (cybercoders??). Resources:

Events / Meetups

Every city hosts tech meetups and networking events, some resources for meetups:

Interviews

I had about 20 interviews before landing a position, split 50/50 between phone and face to face. Numerous companies follow the Google approach of

  • 1 or 2 phone screens
  • 3-5 interviews in one day, each interview with one person.

Each interview was one or two coding questions and some general resume interogation. Having a portfolio of public facing apps is expected, if not then some open source projects.

Code questions

I found the following process to be helpful for programming questions, taken from: Programming problems : A Primer for the technical interview by B. Green. A summary:

1. Reframe: say the problem back to the interviewer, allowing ambiguities to be addressed. And a way to get hints

2. Write test cases: Builds upon step 1, confirms you and your interviewer are on the same page, will help you formulate your solution. Truth tables, expected output for input, corner cases. write them all down without writing the solution

3. Diagram a solution:(e.g): There’s not many general purpose helpers here, hopefully you will have an idea of how to approach the problem based on the test cases and your discussions with the interviewer. Think out loud, they will provide hints if you are stuck.

4. Coding : I like to start start high level and invent lower level functions, keep variable/function names short as possible.

5. Run the test cases from #2: Confirms your solution and allows interviewer to critque

See also:Interviewing the InterviewerCandidate Coaching Session

E3 Visa

Documents

The formulation of documents for my visa was handled by visanow. The process took abou 3 weeks but was pretty straight forward, they have a checklist style interface and good customer service.

visa list

Interview

Held at St. kilda road Melbourne, I had booked for 9:30, arrived at 9 and waited until 10:30 to be seen. There’s an airport style security check where you’ll relinquish any devices.

I bought everything listed from visanow along with some bank statements, bring everything you think will help, but don’t forget:

  • Printed copy of interview confirmation page
  • DS 160 confirmation page
  • Letter of endorsement from your employer
  • Labour condition agreement (ETA form 9035 & 9035E)
  • DHS Form G28

Done!

Almost hard to belive once it happens, the pipe dream is a reality. My role as iOS Developer at Meetup starts in a few weeks, one adventure ends and another is beginning. Thanks for reading.

Fast HTML Rendering Without UIWebView

This project was created for amrc as a means of rendering HTML rich text content.

The library is built on xml parser hpple. htmpple uses NSDictionary merging to produce an NSAttributedString that represents the given html. Only a subset of html tags are supported, they include those available to any rich text editor, layout such as table is too complex to render with just NSAttributedString.

Rendering non-hyperlink content is a peice of cake in iOS 6 due to the support added to [UILabel attributedString] . If the HTML contains links there’s a bit of additional hacking required. I’ve included a subclass of UITextView to assist with this, although you may want to consider delving into CoreText aswell.

The helper method htmlDataContainsLinks is used to detect hyperlinks and mitigate the performance hit when using UITextView

Check out the project on github.com/amleszk/htmpple