Amro Mousa

iOS developer, BMW fan, and amateur photographer.

Read this first

Finding Dependency Cycles in iOS Builds with llbuild UI

Did you know the swift-llbuild project contains a debugging tool called llbuild-ui that can find dependency cycles in your iOS build? To try it:

  1. Enable the New Build System (In Xcode it’s under File, Workspace Settings)
  2. Build your project
  3. Open the Derived Data directory on your machine and find the build.db file generated by the build system. This will be in a path similar to /Users/<yourUsername>/Library/Developer/Xcode/DerivedData/iOS-<someIdentifier>/Build/Intermediates.noindex/XCBuildData/build.db. Take note of this path as you will need it later.
  4. Follow the instructions here to install llbuild UI. You’ll need to have Python (and probably some dependencies) installed on your system.
  5. Start llbuild UI by running the command shown on the Github page linked in step 4 above in terminal.

    FLASK_APP=llbuildui.app venv/bin/python -m flask run

  6. Visit http://127.0.0.1:5000/ in your...

Continue reading →


Diagnosing “Dependency Cycle Between Targets” in Xcode 9’s New Build System

Xcode 9 includes a new build system that can substantially improve build times. The new build system is more strict about build issues, but some of its diagnostic output can be difficult to reason about. One difficult to debug error is “Dependency cycle between targets,” which may appear during incremental builds where you may not have an explicit circular build dependency between targets. Let’s talk about how these types of cycles are introduced and how to troubleshoot and fix them.

There is more than one way to cause this sort of target dependency cycle without adding an explicit target dependency. The behavior of the legacy build system is to continue to (re)build instead of failing. This can increase incremental build times for your project, but the build ultimately succeeds and you may not know there’s a problem. The new build system fails instead, which helps you better maintain...

Continue reading →


Mock Interviews for Fun and Someone Else’s Profit

Last year I started offering mock interviews for iOS developers. It’s been a learning experience for me and, I think, others. I’d like to share a bit about what me and the 10 folks I’ve interviewed so far have experienced and what’s next.

Through the wonder of the internet, I’ve met (and hopefully helped) folks from all over the world. Once a week I interview an iOS developer from anywhere in the world during my lunch hour. I’ve interviewed people from the US, Canada, Italy, Australia, and more. I currently have another 8 interviews lined up with folks from Greece, Singapore, and Brazil to name a few.

Interviews start with about 15 minutes of iOS knowledge questions that cover a wide range of categories from user interface basics to concurrency. I tell candidates that real interviews will go much deeper on each of these topics. This helps them figure out the sort of things they may be...

Continue reading →


Getting Started with Home Automation

Home automation is still an early adopter’s game. The landscape is fragmented and there are competing standards like Insteon, Z-Wave, zigbee, Wi-Fi based devices like Nest and Philips Hue, and Apple HomeKit. And most of these things don’t work together out of the box. ?

So what should you buy? Will it work with iOS via HomeKit or do you have to use a bunch of apps?

I have experience with Insteon, Z-Wave, and Apple HomeKit so I’ll share what I know about those standards here. But first, let’s get some basics out of the way. Setting up Home Automation requires a controller and a responder. (I’ll call responders devices here.)

Controllers
There are many controllers out there. First party controllers generally work with one standard. For instance, Insteon’s hub only talks to Insteon devices. And Samsung’s SmartThings hub talks to Z-Wave devices. I should point out that Z-Wave is not...

Continue reading →


Improving Swift Debug Build Times

It’s well known that enabling Whole Module Optimization greatly reduces Swift build times, but did you know it’s possible to do this for debug builds without breaking the debugger? I didn’t.

Normally, one sets SWIFT_OPTIMIZATION_LEVEL to -Onone for development builds. Otherwise, the debugger will behave in ways that are expected but not helpful.

I wanted the build-time gains that come from enabling Whole Module Optimization without breaking the debugger. After some trial/error, I tried setting SWIFT_WHOLE_MODULE_OPTIMIZATION to YES and, to my surprise, it worked. And the debugger still worked in my testing.

This reduced debug build times by approximately 30% on a project I contribute to.

You might be run into an interesting compiler segmentation fault after enabling SWIFT_WHOLE_MODULE_OPTIMIZATION. If you do, check the build log for a stack trace that mentions SIL optimization...

Continue reading →


Implementing Rich Notifications in iOS 10

I’ve spent a bit of time with notification extensions in iOS 10 and they’re pretty great. If you’re not familiar with notification extensions, check out Apple’s Introduction to Notifications talk before reading this post. Anywho, notification extensions improve your app’s notification experience giving you a chance to mutate notification payloads, download and display media, and show custom interfaces in response to notifications. I thought I’d share a bit about how they work and a few things I ran into while adding notification extensions to an existing app.

Before we dive in, I should mention that iOS 10 brings other fancy notification enhancements like aggregation, a way to handle notification actions in an extension, and the ability to opt into system notification banners for your application while it is open. I’ve chosen to focus on processing and displaying notifications in this...

Continue reading →


Fugly Side Project ???

For the last few months, I’ve spent many of my evening hours working on a side project. Usually that ends with my solving whatever interesting problems there are and moving on to something else. But this time it stuck. I built a Fugly Side Project called Dog Ear that tells you when your servers go down.

I’ve used uptime monitoring services in the past and they all seemed to send false positive alerts too often. At least often enough to bother me. So the implicit goal of Dog Ear is to do less of that. Hopefully much less of that.

Today Dog Ear is light on features. For instance, it doesn’t support multi-region monitoring, though that’s something I’d like to add. And although the web app is responsive, there’s no iPhone or Android app. Alerts are sent via SMS and email thanks to a couple of reliable providers and I have also farmed out credit card processing to Stripe. It’s easier for me...

Continue reading →


Communicating with WCSession

WatchKit on watchOS 2 brings major improvements to how Apple Watch apps communicate with their host app. Gone is openParentApplication(_:reply:), which has been replaced by the more capable WCSession.

 Features

WCSession allows WatchKit apps and their counterpart application to communicate, bidirectionally, in three ways: an updatable Application Context, live messages, and background transfers. The two later communication methods can either send a dictionary of values or raw data.

 Application Context

The Application Context is a dictionary that’s sent to the counterpart and persisted. The dictionary can then be read when the counterpart, whether that’s the WatchKit app or the host app, wakes up.

Updating the Application Context is simple. Just call updateApplicationContext(_:). This replaces the prior context value visible to the counterpart application. Note that updateApplicationC...

Continue reading →


Watch Extension Lifecycle

One useful addition brought by watchOS 2.0 is the WKExtensionDelegate protocol, which exposes lifecycle events and more. This protocol is similar to UIApplicationDelegate.

WKExtensionDelegate has three methods that let you respond to lifecycle events. The lifecycle methods will seem familiar: applicationDidFinishLaunching(), applicationDidBecomeActive(), and applicationWillResignActive().

There are also several methods you can implement to handle notifications.

And finally, you can implement handleUserActivity() to facilitate Handoff.

View →


Building  Watch Apps

I’ve been tinkering with WatchKit in my spare time and thought I’d share a bit of what I’ve learned. Of course, all of my tinkering was done in the simulator as I’ve not actually played with an  Watch.

 Watch Apps Have Up To Three Components

Watch apps contain an application, an optional glance, and optional custom notifications.

Glances are sort of like Today widgets on iOS. The idea is to show the most important bit of information your app provides. For example, CNN might display breaking news. The Watch may create your glance controller some time before the user sees it so it’s important to make sure the information displayed is up to date in willActivate(). Glances can be enabled or disabled by the user, don’t support scrolling, and allow for limited interactivity. Tapping a glance opens your Watch application.

Notifications are baked in with a default look but you can choose to...

Continue reading →