Itty Bitty Labs

Code and technical stuff from Itty Bitty Apps.

Reveal Cyber Monday Sale

We’re closing in on the end of 2014, and the team at Itty Bitty Apps is hard at work polishing Reveal 1.5. Good things take time but we’re sure you’re going to find this next release super useful, with an overhaul of the inspectors, Auto Layout inspection and a bunch of important fixes and updates.

We’re aiming to release Reveal 1.5 early in the new year as a free update to existing customers, and for a short time only we’re offering a 50% Cyber Monday discount for Reveal Personal Licenses. Just enter the discount coupon code REVEAL-CYBER-MONDAY before entering your credit card details here for 50% off. The discount is valid until Wednesday 3rd December 2014 (UTC).

If you’ve been sitting on the sidelines or know of fellow iOS developers who haven’t yet experienced Reveal, now is a great chance to get on board and get the free 1.5 update when it hits next year.

Because nothing makes us happier than happy developers :)



About Sean

Sean Woodhouse is the director of Itty Bitty Apps, creators of the iOS runtime inspection tool Reveal. You can follow him on twitter @seanwoodhouse


New opportunities at Itty Bitty Apps

Itty Bitty Apps is looking for an iOS developer to join the team.

We are a mobile consulting and product development company based in Melbourne Australia. If you’re an iOS developer, you might know us from our runtime introspection tool Reveal. If you’re in Australia and you’ve ever used the realestate.com.au or SEEK apps, you’ve seen some of our handiwork.

We are passionate about great software engineering, UX and design. You will need to be too, and more than that, you’ll need to be able to point to products you’ve worked on that reflect your own high standards.

Our work environment is relaxed but focussed on achieving great results for our clients and delivering ground breaking development tools to our customers. Most of our consulting engagements are on-site with clients, where we can help shape the design and implementation of their mobile products. You’ll need to be enthusiastic about working embedded with their teams and in their environments (largely agile).

Reveal product development is done in-house, and as part of the team you will have opportunities to work on this amazing product.

Our office is located in one of Melbourne’s best laneways for food and coffee in the heart of the city. You will not be left wanting for single origin or cold drip coffee, if that’s your thing.

We can sponsor international applicants via the 457 Temporary Work Visa and permanent residency applications. You will need to have an undergraduate degree to be considered for sponsorship. This could be the opportunity you’ve been looking for to move to one of the most liveable cities in the world.

Candidates with a track record of Open Source contributions and a mastery of multiple programming languages and platforms will be highly regarded.

If you’re interested in applying for this role, send an email to jobs@ittybittyapps.com telling us about your experience and links to examples of your work. Salary packages are commensurate with experience. See the job description below for more details.

No recruiters please.



iOS Developer

Are you an iOS developer looking to challenge yourself and work with a team of A+ players? This is an opportunity to join one of the most respected iOS development companies in Australia and take your skills to a new level.

Responsibilities

  • Design, development and maintenance of iOS and OS X applications.
  • Work with clients directly to help them deliver well architected and implemented mobile applications.
  • Use a number of different languages and technologies to achieve successful outcomes.
  • Maintain high quality standards.
  • Share learnings and insights with others through the publishing of technical articles.
  • Contribute to UX and design discussions.
  • Assist in technical support.

Core Competencies

  • Teamwork: The ability to work effectively in, and help facilitate, a group of people.
  • Problem Solving: The ability to independently and effectively identify and rectify the source of problems.
  • Attention to Detail: Having a keen eye for things that are not right, are out of place or could be done better.
  • Learning: The ability to assimilate new information and effectively apply learnings to new environments and situations.
  • Initiative: Proactively preparing for, and responding to, situations with minimal supervision. Making constructive suggestions and creating novel solutions to problems.

Prerequisites

  • Excellent technical understanding of Objective-C, the iOS platform and development toolchain.
  • Good understanding and practical application of design patterns.
  • Good understanding and experience with testing frameworks.
  • Good understanding and experience developing apps that integrate with RESTful APIs and Web Services.
  • Good understanding and experience with revision control systems such as Git.
  • 2+ years commercial iOS development.
  • 3+ years commercial software development.

Highly Regarded

  • Experience developing OS X applications.
  • Experience developing Android applications.
  • Experience with other languages and platforms (e.g. Java, C, C#, Ruby, Rails, NodeJS, JavaScript, HTML5 and CSS).

About Sean

Sean Woodhouse is the director of Itty Bitty Apps, creators of the iOS runtime inspection tool Reveal. You can follow him on twitter @seanwoodhouse


Swift Swiftly

Oliver recently completed a three-city tour presenting an overview of Swift, Apples’s new language for Mac and iOS development, as part of YOW! Nights.

Swift is still in development, so please keep in mind that some of the things Oliver discusses in this presentation will have changed by the time you view it.


About Sean

Sean Woodhouse is the director of Itty Bitty Apps, creators of the iOS runtime inspection tool Reveal. You can follow him on twitter @seanwoodhouse


AppleScript and Reveal

Recently we released version 1.0.4 of Reveal. At the same time JetBrains released version 3.0 of their Objective-C IDE AppCode. One of the new features in AppCode 3.0 was a plugin that provides integration between Reveal and AppCode. This plugin makes it very easy to get Reveal running with your project and inspecting your iOS app.

But how does this integration work? Well, JetBrains have a blog post describing how to use the bundled plugin and the java source code to the plugin is on github.

If you read the source you might notice that it makes use of a little AppleScript.

Besides bugfixes the only major change in version 1.0.4 of Reveal was the introduction of support for AppleScript. We did this specifically to make the integration with AppCode easier.

But it is not just AppCode that can take advantage of this new AppleScript API.
Xcode users can too. Let me explain…

Getting Reveal’s library to start automatically.

I’ve previously written posts on how you can dynamically inject Reveal’s dylib into your app using dlopen in LLDB. Another technique, the one employed by AppCode, is to use the dynamic linker’s (dyld) environment variables. Specifically the DYLD_INSERT_LIBRARIES variable.

With Xcode the easiest way to use this technique is to modify or create a scheme in your workspace so that the DYLD_INSERT_LIBRARIES environment variable is set to /Applications/Reveal.app/Contents/SharedSupport/iOS-Libraries/libReveal.dylib.

You will have to tweak this path if you’ve not installed Reveal into your system’s root Applications folder.

The image above shows how to set and enable this environment variable. With this environment variable set the libReveal.dylib will be loaded automatically by the dynamic linker every time your app is run in Xcode. Note that this will only work in the iOS Simulator. You will get a crash if this environment variable is enabled when running on an actual iOS device.

Refreshing Reveal automatically when running your iOS application.

The next thing we need to do is get Reveal to automatically connect to your iOS application when it starts. This can be accomplished using a pre-run script action in your scheme.

In the Xcode scheme editor editor expand “Run” and select “Pre-actions”. Add a new “Run Script” action and enter the following script:

Run Pre-action Script
1
2
3
4
5
6
7
8
9
10
(echo "
  tell application \"/Applications/Reveal.app\"
    activate
    delay 4
    repeat with doc in documents
      refresh doc when available application name \"${PRODUCT_NAME}\"
    end repeat
    activate
  end tell" | osascript) &

Note that the trailing ampersand is important! It causes the script to be run in a background sub-shell and avoids delaying your application from starting.

Also ensure that you select your application’s target from the “Provide build settings from” popup button, otherwise the ${PRODUCT_NAME} variable will not be expanded correctly in the script.

Here is a screen shot of these settings:

Note also that there is a delay of 4 seconds in this script. This is there to give the iOS simulator enough time to start up. You may need to tweak this depending on how fast your Mac can start up the simulator. The Simulator also seems to take longer the first time it is launched. Reveal will time out after receiving the “refresh” command if it can’t find your application within 10 seconds.

Here is a video showing this in action:

Refreshing Using a Breakpoint

Another use for the AppleScript support is refreshing Reveal in response to hitting an Xcode break point. This assumes that Reveal is running and connected to your app already (perhaps by using the technique outlined above).

Add a breakpoint at a key point in your application. The method -viewDidAppear: on a UIViewController is a good choice. Edit the break point to add an AppleScript action. The AppleScript should be as follows:

Refresh Reveal
1
2
3
4
5
tell application "Reveal"
  refresh document 1
  activate
end tell

NB: Ensure that the breakpoint automatically continues after evaluation otherwise Reveal will not be able to take a snapshot. Also, if you don’t want Reveal to come to the foreground when the breakpoint is hit, remove the “activate” statement from the AppleScript.

So there you go. A few more gadgets for your iOS view debugging toolbelt. We’re hoping to further expand Reveal’s support for AppleScript in future releases. Let us know if you have any ideas or suggestions on what additional scripting functions we should add.


About Oliver

Oliver Jones is the Technical Director at Itty Bitty Apps. He spends his days building the iOS Introspection tool Reveal and playing Pinball. You can follow him on twitter @orj.

Game On!

So Apple just dumped an amazing amount of new technologies on the iOS and Mac developer community. Heads were spinning and jaws were being picked up off the floor around the world as Apple proved they were innovating like never before, and if you read between the lines, laying the foundation for what appears to be an amazing lineup of new hardware later this year.

The sheer amount of new technologies, SDK’s and API’s was astounding, but the main point of interest for us was Apple’s introduction of runtime view inspection in to Xcode 6. That obviously has implications for our product Reveal and the Twitter-verse was abuzz with mentions of Reveal being ‘Sherlocked’ along with about a dozen other companies and technologies. But before I share my thoughts on Apple’s latest addition to Xcode, I’d like to fill you in on how Reveal came to be.

In 2011 on the way over to WWDC, Oliver and I started talking about runtime inspection of applications and the dynamic nature of the Objective-C runtime. We lamented the fact that games developers had such great tooling and pipelines for rapid iteration while we were still stuck in the change-compile-run workflow that’s been around for decades. There were some opensource tools that hinted at the possibilities but didn’t have the depth or polish we wanted in our own tools. We could see opportunities for making our own development workflow better and for improving the interactions between designers and developers. That led us to focus on runtime view hierarchy inspection but our vision was much more broad.

What you see today in Reveal is really just the tip of the iceberg. We had to deliver a solid foundation, and although we narrowed the scope considerably to get Reveal to market, we never compromised on quality or features we thought were necessary to make it a truly professional tool. These include the ability to collapse the view hierarchy in the outline and canvas, drilling down to see just one part of the hierarchy, accurate rendering of the hierarchy, no (or limited) side effects of linking your application with the Reveal library, navigation keyboard shortcuts, comprehensive inspectors, undo/redo and all the other polish expected of professionally developed and supported Mac OSX applications. It was clear to us from the start that basic view inspection would become commoditised, but as is always the case, it would be the care and attention to detail that elevates one product above the rest.

So that brings us to Apple’s introduction of runtime view hierarchy inspection in Xcode 6. On first inspection the similarities are obvious. Scratch the surface and you’ll find it’s much more limited. In fact the way it’s been implemented you have to pause the application in the debugger to take the snapshot and it’s read-only, meaning you can’t change anything in the view hierarchy to see it update dynamically. This is worlds apart from what Apple demonstrated with Playgrounds, which is much more in line with our thinking.

I won’t go in to a blow-by-blow comparison in this post since it might be deemed a review by Apple, suffice to say we have a test suite we use to make sure Reveal deals with all sorts of scenarios and Apple’s inspector fails at many of them. What they’ve delivered in this first version is basic and rough, but it is a beta and we expect them to fix the bugs over time. Will they invest the time, effort and resources needed to create the best runtime view hierarchy inspection tool on the market? I doubt it, and I’m literally putting my money where my mouth is.

The reality is that if we all stood back and waited for Apple to innovate we’d be beholden to their way of thinking, project schedules and priorities. Companies like JetBrains and Xamarin have shown that alternative commercial development tools can succeed despite Apple’s toolchain monoculture.

If you were impressed by what you saw from Apple and haven’t tried Reveal I’d encourage you to download it and try it out. Don’t make comparisons and assumptions based on screenshots alone. We have a 30 day trial you can download here and if you have any questions or need support, we’re available to help here.

Lastly, thank you Apple for validating that runtime view inspection is an important part of the development workflow. We’ll gladly assume the position of leader in this space.


About Sean

Sean Woodhouse is the director of Itty Bitty Apps, creators of the iOS runtime inspection tool Reveal. You can follow him on twitter @seanwoodhouse


Reveal your iOS applications from AppCode

It gives me great pleasure to announce that we have been working with our friends at JetBrains to bring Reveal integration to AppCode. The integration is by way of an AppCode plugin that allows you to configure your iOS project to have the Reveal library injected in to them at runtime.

To try the integration for yourself you’ll need to be running AppCode 3.0 EAP build 137.48 and Reveal 1.0.4. If you have an earlier version of Reveal installed you can update to v1.0.4 by selecting the Reveal/Check for Updates… menu. Please also delete any other copies of Reveal you have on your system.

The latest AppCode 3.0 EAP ships with the plugin already installed but you need to configure your project to inject the Reveal library at launch and to optionally deploy the library if you’re running on device.

Run or Debug your application and you’ll notice that you can inspect it by pressing the ‘Show in Reveal’ button.

Reveal will then start (if it hasn’t already) and refresh its snapshot of the application. Note: if you haven’t upgraded to Reveal 1.0.4 you will not see the ‘Show in Reveal’ button in AppCode. Under the covers the plugin uses a combination of dynamic library loading and new AppleScript support for refreshing Reveal introduced in v1.0.4.

You can find more information about the AppCode EAP release on their blog, forums and submit bugs and feature requests via the AppCode Issue Tracker. You can also head over to our support site if you’d like to send us feedback directly.

I hope you’re as excited as we are that two of the most powerful tools available to iOS developers now work seamlessly together.


About Sean

Sean Woodhouse is the director of Itty Bitty Apps, creators of the iOS runtime inspection tool Reveal. You can follow him on twitter @seanwoodhouse


Subjective-C: Deconstructing iOS User Interfaces

Our iOS user interface prodigy Sam Page has been busy lately. He’s created a new resource for UIKit programmers called subjc.com.

He has already published a few detailed investigations & deconstructions of user interface elements from recent interesting iOS apps.

Check out these excellent articles and follow him on Twitter.


About Oliver

Oliver Jones is the Technical Director at Itty Bitty Apps. He spends his days building the iOS Introspection tool Reveal and playing Pinball. You can follow him on twitter @orj.

The UIView that wouldn’t be centered

Recently I was creating a banner for an informational page in one of our iOS apps. The designer had specified three centered lines of information about a property, as a static header above a map and some scrolling information below. As you would think, a perfect case for contained view controllers and constraint-based layout. But what appeared to be the easiest part turned to contain an interesting problem…. The base view controller (“self”) starts by apply some basic constraints to a UIView named bannerView at the top of the screen. (The iOS6 case is not shown here for clarity):

Adding constraints to the banner view
1
2
3
4
5
6
7
  if ([self respondsToSelector:@selector(topLayoutGuide)])
  {
    NSDictionary *viewsToConstrain = @{@"topLayoutGuide" : self.topLayoutGuide, @"bannerView" : self.bannerView};

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topLayoutGuide][bannerView]" options:0 metrics:nil views:viewsToConstrain]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bannerView]|" options:0 metrics:nil views:viewsToConstrain]];
  }

The banner view is anchored to the top of the view controller’s view and is constrained to its full width. At this stage bannerView has no frame set and won’t display anything, so it needs to supply its own height constraint. This is achieved by relying on the intrinsic height of its contents – each label is placed in the banner view and centered horizontally by constraint, then bannerView has a constraint applied that stacks each view and at the same time gives the view its intrinsic height, the total of the heights of those views. You could say it really ties the view together. (This is one of the tough concepts in auto layout: constraints don’t apply in one direction, they are all applied and solved simultaneously. Conflicts and ambiguities are the only problem, either the parent or the subview can supply the dimension.) An example:

Centering horizontally and stacking vertically
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  self.addressLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  // font, color, text etc. are set 
  [self.addressLabel sizeToFit];
  self.addressLabel.translatesAutoresizingMaskIntoConstraints = NO;
  [self addSubview:self.addressLabel];

  // horizontal centering is repeated for the locality label and the features view (not shown)
  [self addConstraint:[NSLayoutConstraint constraintWithItem:self.addressLabel
                                                   attribute:NSLayoutAttributeCenterX
                                                   relatedBy:NSLayoutRelationEqual
                                                      toItem:self
                                                   attribute:NSLayoutAttributeCenterX
                                                  multiplier:1.0f
                                                    constant:0.f]];

  // create and apply the constraint to position everything vertically. All these views have an intrinsic height so bannerView (self) 
  // will have the total height of these views
  NSDictionary *viewsToConstrain = @{@"addressLabel" : self.addressLabel, @"localityLabel" : self.localityLabel, @"featureView" : self.featureView};

  NSString *vFormatString = [NSString stringWithFormat:@"V:|-%f-[addressLabel]-%f-[localityLabel]-%f-[featureView]-%f-|",
                             kAddressLabelTopMargin, kLocalityLabelTopMargin, kFeatureViewTopMargin, kViewBottomMargin];
  [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vFormatString
                                                               options:0
                                                               metrics:nil
                                                                 views:viewsToConstrain]];

The end result is the completed bannerView, anchored to the top of the containing view controller’s view. If the designer decides to alter the font size or order of the labels or the size of featureView then the banner view will be resized through its constraints automatically. In the view controller the next lower view is anchored to the base of the banner view so everything maintains its arrangement. Job done! Or so I thought. A look at the result shows not the three nicely centered elements expected, but two centered elements and one seemingly left aligned on the centre. As the bannerView has been selected, Reveal shows its bounds (in 2d mode) with the blue outline. That’s strange, since the view has the same NSLayoutAttributeCenterX constraint applied as the labels. The featureView is actually a view containing a single label. Once upon a time it was a view containing three icons and three labels, but to improve scrolling efficiency (remove transparency) a font was created containing glyphs for those icons, and the view created using the label’s attributedText property. For a quick sanity check, what if the view is a plain UIView?

Testing with a simple view
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  self.featureView = [[UIView alloc] initWithFrame:CGRectZero];
  self.featureView.backgroundColor = [UIColorblueColor];
  [self.featureView addConstraint:[NSLayoutConstraint constraintWithItem:self.featureView
                                                               attribute:NSLayoutAttributeHeight
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:NSLayoutAttributeNotAnAttribute
                                                              multiplier:1.0
                                                                constant:28.f]];
  [self.featureView addConstraint:[NSLayoutConstraint constraintWithItem:self.featureView
                                                               attribute:NSLayoutAttributeWidth
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:NSLayoutAttributeNotAnAttribute
                                                              multiplier:1.0
                                                                constant:120.f]];

So everything is working with a plain view. Why doesn’t the features view work? The reason this view changed is because Instruments called it out as containing transparency. Image blending can really hurt scroll performance and you can find out which views have the feared transparency with Instruments – while running on a device with the Core Image instrument, check the “Color Blended Layers” box. You will find everything shaded green except for those views that use transparency, and they will be red. Red indicates SLOW. One way to get around this is to use opaque source images and arrange your layout so that no transparency is required. Another is to switch strategies, as in this case. A label using attributed strings created with a font designed with custom glyphs (replacing the original transparent UIImageViews) doesn’t trigger this warning. Examining the creation of the view reveals nothing to worry about. Strictly speaking this label could be added as a label rather than adding a label to a view and then using the view, but it remains the way it is to avoid touching too much other code that expects it to be a view. Experimenting with the internals of the view doesn’t change the way it left aligns on the centre either. Time to bring up the big gun, Reveal.

Looking at the UIView portion of Reveal’s inspector window for the feature view vs. the UILabel above it shows right away that there is no intrinsic content size set for the feature view, and it has a bounds of CGRectZero. This hasn’t mattered previously because the feature view has been used with conventional layout, explicit frame setting rather than constraints. What happens if an intrinsic content size is supplied for the custom class?

Adding intrinsic content size
1
2
3
4
5
6
7
8
  // after creation of the UILabel 
  [self invalidateIntrinsicContentSize];

// Later on in the class...
- (CGSize)intrinsicContentSize {

  return self.label.frame.size;
}

Running the app again shows that the view is just where it should be. A quick look in Reveal shows the intrinsic content size is as expected – clicking on the feature view shows its intrinsic content size is the same as for the label it contains, as we want. Adding a new view controller using constraint-based layout exposed an issue that didn’t cause problems in frame-based layout. Reveal uncovered the problem and verified the solution.


About Adam

Adam Eberbach is an iOS Developer at Itty Bitty Apps. He has worked on the iOS introspection tool Reveal and the Realestate.com.au iPhone/iPad App. You can follow him on twitter @aeberbach

We’re hiring!

Update April 2nd, 2014: We are no longer actively looking to fill these roles, but we are always on the lookout for great people. If you’re interested in working at Itty Bitty Apps please send an email to jobs@ittybittyapps.com and introduce yourself!


Itty Bitty Apps is looking for a number of talented iOS, Android and Mac developers to join our team.

We are a mobile consulting and product development company based in Melbourne Australia. If you’re an iOS developer, you might know us from our runtime introspection tool Reveal. If you’re in Australia and you’ve ever used the realestate.com.au or SEEK apps, you’ve seen some of our handiwork.

We are passionate about great software engineering, UX and design. You will need to be too, and more than that, you’ll need to be able to point to products you’ve worked on that reflect your own high standards.

We are intimately involved in the iOS and Mac development community in Australia, organising Melbourne Cocoaheads meetups which regularly attract 80+ attendees each month. We’ve also been instrumental in organising Swipe, Australia’s first iOS and Mac developer conference. You will need to have a similar passion for community and knowledge sharing.

Our work environment is relaxed but focussed on achieving great results for our clients and delivering amazing development tools to our customers. Most of our consulting engagements are on-site with clients, where we can help shape the design and implementation of their mobile products. You’ll need to be enthusiastic about working embedded with their teams and in their environments (largely agile).

Reveal product development is done in-house, and whether you join us as an iOS or Android developer, you will have opportunities to work on this amazing product.

Our office is located in one of Melbourne’s best laneways for food and coffee in the heart of the city. You will not be left wanting for single origin or cold drip coffee, if that’s your thing.

We can sponsor international applicants via the 457 Temporary Work Visa and permanent residency applications. You will need to have an undergraduate degree to be considered for sponsorship. This could be the opportunity you’ve been looking for to move to one of the most liveable cities in the world.

Candidates with a track record of Open Source contributions and a mastery of multiple programming languages and platforms will be highly regarded.

If you’re interested in applying for any of the following roles, send an email to jobs@ittybittyapps.com telling us about your experience and links to examples of your work. Salary packages are commensurate with experience.

No recruiters please.



iOS Developer

Are you an iOS developer looking to challenge yourself and work with a team of A+ players? This is an opportunity to join one of the most respected iOS development companies in Australia and take your skills to a new level.

Responsibilities

  • Design, develop and maintain iOS applications for clients in-house.
  • Work with our clients on-site to help them deliver well designed and implemented mobile apps to their customers.
  • Contribute to UX and design discussions.
  • Post technical content to the Itty Bitty Apps blog.

Prerequisites

  • Excellent technical understanding of Objective-C, the iOS platform and development toolchain.
  • Good understanding and practical application of design patterns.
  • Good understanding and experience with testing frameworks.
  • Good understanding and experience developing apps that integrate with RESTful APIs and Web Services.
  • Good understanding and experience with revision control systems such as Git.
  • 2+ years commercial iOS development.

Highly Regarded

  • Experience developing Android applications.
  • Experience with other languages and platforms (e.g. Java, C, C#, Ruby, Rails, NodeJS, JavaScript, HTML5 and CSS).


Android Developer

Have you been doing Android development for a few years? Looking for your next challenge? This is an opportunity to join us as a lead Android developer, share your knowledge with the team and develop some amazing products.

Responsibilities

  • Design, develop and maintain Android applications for clients in-house.
  • Work with our clients on-site to help them deliver well designed and implemented mobile apps to their customers.
  • Develop frameworks and libraries for use across applications.
  • Contribute to UX and design discussions.
  • Mentor other developers on the team.
  • Post technical content to the Itty Bitty Apps blog.

Prerequisites

  • Excellent technical understanding of Java, the Android platform and development toolchain.
  • Good understanding and practical application of design patterns.
  • Good understanding and experience with testing frameworks.
  • Good understanding and experience developing apps that integrate with RESTful APIs and Web Services.
  • Good understanding and experience with revision control systems such as Git.
  • 2+ years commercial Android development.
  • 4+ years commercial development on other platforms.

Highly Regarded

  • Experience developing iOS applications.
  • Experience with other languages and platforms (e.g. Java, C, C#, Ruby, Rails, NodeJS, JavaScript, HTML5 and CSS).


Mac Developer

Are you an old hand at AppKit? Been cutting Objective-C since the NeXT days? Are you constantly telling those UIKit whippersnappers to get off your lawn? Have you been instrumental in delivering complex Mac apps to market? If so, you could be the one to help take Reveal to the next level. This is a unique opportunity to become a core member of the Reveal development team.

Responsibilities

  • Design and implement new features of the Reveal client and server applications.
  • Fix bugs and refactor existing code.
  • Development of custom AppKit UI components.
  • Help triage and prioritise features on the product backlog.
  • Reply to technical support questions.
  • Mentor other developers on the team.
  • Post technical content to the Itty Bitty Apps blog.

Prerequisites

  • 4+ years commercial AppKit development.
  • Experience developing client-server and/or peer-to-peer applications.
  • Experience developing custom Appkit UI components.
  • Solid understanding and experience with Core Graphics.
  • Good understanding and experience with revision control systems such as Git.
  • You must be able to reference commercially released Mac software you have developed (or been substantially responsible for developing).

Highly Regarded

  • Commercial experience developing iOS applications.
  • Experience with Scene Kit.
  • Experience developing IDE’s (even on other platforms).
  • Experience with other languages and platforms (e.g. Java, C, C#, Ruby, Rails, NodeJS, JavaScript, HTML5 and CSS).

About Sean

Sean Woodhouse is the director of Itty Bitty Apps, creators of the iOS runtime inspection tool Reveal. You can follow him on twitter @seanwoodhouse


Working with iOS 6 and 7

If business reasons require you to continue supporting iOS 6, this means you may need to work with both iOS 6 and 7 for quite a while. Developers always hate this, as it may increase the code base cyclomatic complexity (e.g. if iOS 6 do this, else if iOS 7 do that…) . I love it, since my wife, mum, dad and manager are still using iOS 6.

Layout issue on iOS 7

Here is a very simple app running on iOS 6.

After switch the simulator to iOS 7, the label is missing

Why? Let’s reveal it.

The label is actually behind the NavigationBar. In iOS 7, apple introduced a new property called [UIViewController setEdgesForExtendedLayout:] and the default value is UIRectEdgeAll. When your container is navigation controller, the default layout will start from the top of navigation bar. This is why all of the UI elements had been shift up 44pt.

A quick way to fix this issue is add the following snippet to method - (void)viewDidLoad.

Fix Layout issue
1
self.edgesForExtendedLayout = UIRectEdgeNone;

Now, it’s been fixed.

iOS 6 runtime exception

Let’s run the app on iOS 6 then, we found the following runtime exception.

iOS 6 runtime exception
1
[LAViewController setEdgesForExtendedLayout:]: unrecognized selector sent to instance 0x778a210

All iOS 7 only API invokes need to be wrapped with proper guarder.

1
2
3
4
if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
{
    self.edgesForExtendedLayout = UIRectEdgeNone;
}

Xcode 4 compile error

Some machines might still running with a Xcode 4.6. When they pull the latest code, they will fail to compile then.

1
2
Property 'edgesForExtendedLayout' not found on object of type 'LAViewController *'
Use of undeclared identifier 'UIRectEdgeNone'

To avoid the compile stage error, we need to create the following macro.

1
2
3
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
#define IOS7_SDK_AVAILABLE 1
#endif

Then wrap the iOS 7 code path if needed.

1
2
3
#ifdef IOS7_SDK_AVAILABLE
...
#endif

UILabel background inconsistency

As a UILabel, iOS 7 default background color is clearColor (which make sense most of the time), while the iOS 6 default value is white. So we’d better to explicit set the label background color.

1
view.backgroundColor = [UIColor clearColor];

Hide status bar while in full screen

In iOS 6, when we call presentViewController, the default modal screen will be full screen. (UIModalPresentationFullScreen). In order to achieve a consistent experience on iOS 7, we add the following code to modal controller.

1
2
3
4
- (BOOL)prefersStatusBarHidden
{
  return YES;
}

[UIToolbar barStyle]

We used UIToolbar with the system keyboard (Actually, it’s IBAForms and EZForm using them). As the iOS 6 keyboard is in dark skin, people style the toolbar like this.

1
self.barStyle = UIBarStyleBlack;// or UIBarStyleBlackTranslucents

Coming to iOS 7, the keyboard skin becomes lighter, so we need different barStyle for various iOS version.

1
2
3
4
5
6
7
8
if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
{
    self.barStyle = UIBarStyleDefault;
}
else
{
    self.barStyle = UIBarStyleBlack;//or UIBarStyleBlackTranslucent
}

More than that…

It is definitely more than that. The above tips are just some of the most common issues I have seen when working on iOS 6 & 7 codebases.


About Long

Long Sun is an iOS Developer at Itty Bitty Apps. He has worked on the iOS introspection tool Reveal and Realcommercial iPhone/iPad App. You can follow him on twitter @spritesun