Reviving Shopster - Deprecations and iOS 10

A nice thing about reviving a project, is that I get to choose the target platform again. In this case, I don’t see a reason not to make it iOS 10 only: up until iOS 9, the app worked (even if it was not optimized for), so users of iOS 9 can remain on the old version.

This gives me the chance of remove a lot of old stuff that I had laying around, mainly to support older OS versions.

Reviving Shopster - Baseline Metrics

Before any change to the codebase (apart for making it build), I figure it’s a good idea to have a baseline of the amount of code the app has. For that, I’ll use cloc. Here’s the initial output:

127 text files.
127 unique files.
25 files ignored. v 1.70 T=0.74 s (137.4 files/s, 8946.6 lines/s)
Language files blank comment code
Objective C 47 1200 493 3688
C/C++ Header 53 296 372 476
JSON 2 0 0 117
SUM: 102 1496 865 4281

This was run only on the folder where our code resides, so it’s excluding all external dependencies (basically, the Pods folder).

Reviving Shopster - Make It Build

I started analyzing wether it was worth reviving Shopster or not.

So first step into the plan: clone the project’s repo, and see what breaks.

For starters, I did not follow my own CocoaPods suggestion1, so the Pods folder is not part of the repository.

Luckily, Shopster’s Podfile is pretty short:

platform :ios, '7.0'
xcodeproj 'Groceries'
pod 'PSAlertView'
pod 'TestFlightSDK', '~> 3.0'
pod 'BlockAlertsAnd-ActionSheets', '~> 1.0'
pod 'FMMoveTableView'
pod 'OHAttributedLabel', '~> 3.4'

Apart from these Pods, we are using Crashlytics and AskingPoint, which I no longer would like to have in the app.

First step to fix the Podfile then: remove old dependencies (TestFlight was acquired by Apple long ago!) and adopt the new syntax. The resulting Podfile looks like this:

platform :ios, '7.0'
project 'Groceries'
target 'Shopster' do
pod 'PSAlertView'
pod 'BlockAlertsAnd-ActionSheets', '~> 1.0'
pod 'FMMoveTableView'
pod 'OHAttributedLabel', '~> 3.4'

This new Podfile has this warning: [!] OHAttributedLabel has been deprecated in favor of DTCoreText. I’ll deal with that later.

I also removed AskingPoint.framework. The project still fails to build. The pch (remember those?) is including <TestFlightSDK/TestFlight.h>, and of course, I’m initializing it in the AppDelegate and using it in a reporter class. Removing these makes the project build!

Current state: Shopster runs on the iOS 10 Simulator, just like it runs on my iPhone. All the low hanging fruit has been taken care of.

  1. No wonder why: the post is from May 2014, and Shopster is from June 2013. A testament of how can I change my opinion on tools usage in a year.

Reviving Shopster - Worth It?

We launched Shopster in 2013. It was the last app we developed we published under Quadion’s name. Even though it had great launch coverage, it tanked.

For 2016 standards, the app has piled up on technical debt. It currently:

  • Doesn’t dupport screen sizes larger than the 4’ iPhone 5.
  • Is not using auto-layout.
  • Uses several deprecated APIs.
  • Has workarounds for several things.

And, of course, it’s 100% Objective-C, as Swift was not around by the time we wrote it.

So, what would be the motivation to keep investing in it?

  1. We like the app. We still keep it in our home screens and use it.
  2. It still has some users (iTunes reports about 100 active users per day).
  3. Is an app we like to showcase.
  4. We could try a new business model.

And finally, we got a ticket last week asking us to please, please, add support for iOS 10.

On Sharing

When we launched Shopster, we neglected to include a sync feature. We figured it was not that important, but our users kept asking for it.

By the time we had to make the call, the best choice was to roll our own syncing engine and incur in a monthly cost, knowing almost for certain, that we might not be able to afford it in the long run.

Fast forward a few years, and Apple shipped CloudKit and more recently CloudKit sharing, which would allow us to enable sharing of shopping lists at no monthly cost.

Will we do it?

I’m not sure. What I’ll sure do (and write about) is see the state of our app, and what’s the effort involved in bringing it back to life.

Prevent Your Mac From Sleeping With Caffeinate

I’ve known caffeinate for a long time, but I found a new use today that prompted me to write about it.

For those you don’t know, caffeinate is a command line tool that prevents your Mac from going to sleep. From it’s man page:

caffeinate creates assertions to alter system sleep behavior. If no assertion flags are specified, caffeinate creates an assertion to prevent idle sleep. If a utility is specified, caffeinate creates the assertions on the utility’s behalf, and those assertions will persist for the duration of the utility’s execution. Otherwise, caffeinate creates the assertions directly, and those assertions will persist until caffeinate exits.

Let’s say you need to run a long task, like restoring a DB in postgres with pg_restore. The way you use caffeinate would be to run:

$ caffeinate -i pg_restore database database.dump

But let’s say you forgot to run caffeinate and your process has already been running for too long to cancel and restart. Before today, my approach was to use Caffeine to prevent the Mac from going to sleep. However, there’s a second way to invoke caffeinate:

$ caffeinate -i -w 12345

where 12345 is the pid of the process you want to finish without the Mac going to sleep.

Apple TV and Universal Search 

An old article, but I have some thoughts:

“At launch we’ll have iTunes, Netflix, Hulu, Showtime, and HBO — so we’ll have five major inputs into universal search initially,” Cook said. “But we’re also opening an API, so that others can join in.”

I still have some questions:

  • How open will this API be? Any app can join? How do you prevent YouTube from populating your search results? What about Plex, or other apps that can play content not guaranteed to have been obtained legally?
  • From the demo we got, it seems that if you search for a movie or TV Show, you get a single screen with its metadata and sources to play from. How will Apple make movies and TV Shows unique on this search? Will they provide some sort of tool to look up the unique identifier of a given movie or show?

BetterTouchTool vs MagicPrefs

Ever since I got a Magic Mouse, I’ve been using MagicPrefs to configure a middle click on it (basically, to open Safari tabs in the background).

With El Capitan, Apple added a feature to shake the mouse to find the pointer. Even though I don’t need it too much, I was bummed to discover that this feature failes with MagicPrefs, so it gave me a good excuse to try BetterTouchTool instead, which works with this feature.

Overall, I like MagicPrefs better (it’s a System Preferences pane instead of only an app, and the settings are less cluttered), but I’ll be sticking to BetterTouchTool for now.

Using Nscurl With Self-Signed Certificates

New with iOS 9 and Mac OS X 10.11 is ATS, App Transport Security. To help you troubleshoot HTTPS settings, Apple is providing a command line tool called nsurl.

As I’m using a Self-Signed certificate, nscurl fails for me with all its settings. Something like this:

TLSv1.2 with PFS disabled
2015-10-06 18:11:59.609 nscurl[39559:5040069] CFNetwork SSLHandshake failed (-9801)
2015-10-06 18:11:59.610 nscurl[39559:5040069] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)
Result : FAIL

As far as I could find, there’s no parameter to specify a certificate to be used. The only work-around I was able to use is:

  1. Install the certificate on your Mac’s keychain.
  2. Using Keychain Access, change the trust settings of the certificate to “Always Allow”.

With this change you should be able to run nscurl and see the results. Please remember to remove the certificate from your keychain afterwards.