When Oursky moved into a new office in Lai Chi Kok, my colleagues discovered that there was no guide to reset the door lock left by the last tenant. Firstly, we were too cheap to replace it, and secondly, it was a great chance to implement an open door feature with some new tech (fiddling with a bit of IoT). (Ok! I admit it is a bit over-engineered! But we just love it!) I also hope no one needs to get up to open the door when the doorbell rings. Ever.
By the way, I’m Steven, a 3-year Ourskyer specializing in web and native iOS app development. Chima Open Door is one of Oursky’s many side projects — some for fun, and some that actually make money!
You’ve been working hard preparing for your launch to AppStore. The final step is getting it submitted to iTunesConnect.
You have to fill in the app details, upload the app icon, localized descriptions and preview images— upload them one-by-one going through your list of localizations for each supported device in English; one-by-one for each device in French; one-by-one for each device in German, etc, etc.
OK, 13 languages.
You have to upload screenshots one-by-one for each device, for each locale. Oh that’s O(n²)
Let’s say you have built an awesome app for iPhone & iPad and now it’s ready for launch.
Question, how many preview images exactly do you have to add?
The answer is simple. For each locale, there are 3.5-inch, 4-inch, 4.7-inch, 5.5-inch and iPad screenshots (and don’t forget the upcoming iPad Pro). There are 5 images in each set, that gives you 5 x 5 = 25 pcs for each locale.
Needless to say, you will have to organize 25 x 13 = 325 preview images to iTunesConnect. Sounds scary right?
In WWDC2015, Apple announced iOS 9 for iPhone and watchOS 2 for iWatch. It has been a huge revamp for watchOS. Not until now, a watch app finally runs natively on the watch.
That means the code is now executing on your watch instead of the phone. By reducing multiple times of data transfer between devices, this is going to make the app loads a lot quicker and responds in a shorter period of waiting time.
watchOS 1 WatchKit Extension runs on the phone and the Watch App is more like a display console for your app.
watchOS 2 WatchKit Extension now runs on the watch, you don’t have to run a watch app with the phone connected actively.
Spentable is a handy, in-your-pocket app that helps you to track your expenses and make purchasing decisions. Now you can even track you daily expense via the watch App without taking out your phone.
In this post, we will talk about the experience on building an app for watchOS 2.
Since the watch app is now running on the watch as a native extension, there are situation we need to handle data sync between the phone and the watch. For example, we wish expense input via the watch will be reflected on the phone instantly.
Get connected to the phone: Watch Connectivity Framework
In watchOS 1, the watch app must be connected to the iPhone app (we call it the main app) to work. We often call [openParentApplication:reply:] to send a message to the iPhone app. However, now the connections in watchOS2 are handled by the Watch Connectivity Framework.
The Watch Connectivity Framework provides a seamless background connection between iPhone and iWatch. It helps doing all the synchronization work between the main app and the watch app. When the watch app handles a user input say, a new expense item, it has to notify the main app and get the record updated. The could be easily done via the Watch Connectivity Framework.
This allows Device-to-device communication more freely (such as transferring files, user infos and application context around ). There are serval APIs to transfer particular data for different use cases.
We have been using Sentry for collecting crash reports and stack traces for our front-end js, Python, and Rails applications. It is reliable with affordable pricing. Simple to setup with it’s open-source SDK.
However, there’s a fundamental problem when it comes to iOS.
What? No symbolized data returned?
Sentry only returns the crash report with a piece of memory address but not a meaningful method name.
As an iOS developers, you should have noticed that it requires a dSYM file to symbolize the stack trace. It helps to identify these addresses with the appropriate dSYM file.
We thought we can upload dsym files and get symbolized information returned when Sentry claims it works on iOS.
The MVC Architecture is generally used in developing iOS applications.
However the “ViewController” approach widely used is the most evil part that messes up Views and Controllers: Developer writes both view animation and business logic in the UIViewController, hence introducing a MEGA-ViewController.
In this passage, we will share our experience on how VIPER saves our lives from this monster in one of our projects.
VIPER is not a framework but an approach to iOS application architecture, which stands for:
View and Controller are wrapped in a single UIViewController class. The UIViewController class constraints the fundamental view management of the iOS app. As the name convention suggests, view controllers often handle both business logics and logics for responding to user interactions.
Over the years, we’ve been building loads of nicely-crafted iOS applications for our clients.
To keep everyone work closely, we send daily builds to our QA Team, beta users, clients, other team members. However, building an iOS is still painful for Project Manager — It involves compiling, uploading the app to TestFlight or HockeyApp,
setting up Crittercism for collecting crash reports (Those who have experience, should know that you have to upload dSym files for symbolic debug messages), notify everyone on Slack, etc.
Much better if we can automate all these with each Pull Request.
CI has delighted us (and other worldwide developers) by being able to :
Automate the unit-testing process
Standard build settings
Maintain a code repository
Support multiple build targets
However, whenever initiating a project, our engineers have to spare some time (and that’s not short) setting up configurations for CI, including dealing with iOS Provisioning profiles, build settings, dependencies, etc.
Upon spending time setting up a few iOS Apps,
“Are we repeating ourselves?” yelled the voice from inside.
We’ve also noticed that the bottleneck for delivering a build is at the “Developer → QA” process
In legacy time, upon a beta build delivery, the PM has to :
Ask the developer to push code to beta branch
Pull code from the beta branch
Fix cert and dependencies
Build the app
Upload to Testflight / Hockey App
Update dSym file at Crittercism
Notify QA Tester / Client the build is available
By building on Travis CI, we partially saved the PM’s life by automating the building and environment configuring process.
The well-built (and tested) project build is now ready for delivery.
Why don’t we further automate the delivery stage?
Beyond Auto-building – Automating the delivery process
Our engineers prepared a reusable script that basically helps initiate the Travis CI settings for every iOS project.
With proper settings and valid API keys, the deliverable built on Travis CI will then be delivered to other App distribution platforms.
Developers only have to put required the certificates, provisioning profiles and API Keys in the corresponding directories.
Then fill in the blanks for project settings in travis.yml.
The repository also includes scripts that enable signing and uploading. Project code will be compiled upon pushing to branches, then uploaded to Testflight / HockeyApp, and the dSym files will go to Crittercism as well.
Now, the latest build will be built and delivered automatically, available for beta testing in a minute.
Oh, we even have the build result pushed to Slack. So other team members in channel could keep track on the progress.
Life gets better
Required Set-up time for Travis CI : 1 day (Before) → 30mins (After)
Steps to deliver a build : Push, pull, fix dependencies, build, upload to various places, delivered (Before) → Push, delivered (After)
Bonus: Sometimes a project could be built on Bob’s machine but not in Ada’s.
Integrating the CI process also standardizes build settings among developers (CI setting as the standard).