Under The Bridge Under The Bridge

Category: Programming
How To Be Evil: Guide To Violating iOS User Privacy

Remember last year there was this fuss about apps harvesting your location data and selling it? 

The curious case of Accuweather and other apps selling our location data

Well, if you were doing that, the news today is Apple’s not going to put up with it, apparently:

Apple finally decided to start enforcing guidelines on selling location data

So the question that’s no doubt on your mind today then, Dear Evil™ Readers, is: What ways are left to be Evil™ to my users?

As it happens, and this is just the strangest thing, since fastlane was purchased by Google, it seems that the main thing @KrauseFx has been working on is compiling a Manual Of How To Be Evil™:

Privacy research

I work on privacy research projects for the iOS platform in my free time. Those projects are in no way affiliated with my work or my employer…

Definitely not, we’d never suspect that! It’s not as if that employer has repeatedly needed to pay out tens of millions of dollars for privacy breaches…

oh, wait.

All kidding aside, you probably want to read through the collection of articles on that page to be aware of things that could happen to you and how to protect against them, even if you’re not planning to Use Them For Evil™ — 

— or, as may happen, inadvertently. No, seriously. In iOS Privacy: watch.user, that bit about

take pictures and videos without telling you
upload the pictures/videos it takes immediately

Yeah, that was one of the more memorable bug reports we’ve had, back in this kinda-Vine kinda-Instagram thing we worked on back in the day:

QA: Troll, why is your code uploading pictures of my girlfriend?

TROLL: Dude, my code is not uploading pictures of your girlfriend.

QA: *holds up device*

TROLL: Huh. OK … how is my code uploading pictures of your girlfriend?

(Lesson Learned there: even if you use timers only for photo countdowns, your app should listen for applicationSignificantTimeChange, or strange things may happen.)

But the one that we actually want to draw your attention today that you definitely need to read is how to protect your app from other people using it for Evil™:

Trusting third party SDKs

Third-party SDKs can often easily be modified while you download them! Using a simple person-in-the-middle attack, anyone in the same network can insert malicious code into the library, and with that into your application, as a result running in your user’s pockets.

31% of the most popular closed-source iOS SDKs are vulnerable to this attack, as well as a total of 623 libraries on CocoaPods…

… What’s the worst that a malicious SDK could do?

  • Steal sensitive user data, basically add a keylogger for your app, and record every tap
  • Steal keys and user’s credentials
  • Access the user’s historic location data and sell it to third parties
  • Show phishing pop-ups for iCloud, or other login credentials
  • Take pictures in the background without telling the user

The attack described here shows how an attacker can use your mobile app to steal sensitive user data…

And as an aid to that, there’s a repo set up now:

Trusting SDKs – HTTPs

A crowd-sourced list of SDKs and how they protect their downloads with HTTPs.

Based on the Trusting SDKs post by @KrauseFx this repo contains a crowd-sourced list of SDKs and their status when it comes to security when downloading the binary or source code…

Since you are responsible for your app’s behaviour whether the source of Evil™ is your code or your SDKs’ code, it behooves you considerably to acquaint yourself with the risks here — so read up thoroughly, and good luck with not being the next privacy-violating headline!

Swift Four -point- One And All

Looks like a particularly Good Friday today: It’s iOS 11.3 Day, which means Xcode 9.3 Day, which means we have a new Swift to learn:

Swift 4.1 Released!

Swift 4.1 is now officially released! It contains updates to the core language, including more support for generics, new build options, as well as minor enhancements to Swift Package Manager and Foundation. There was also significant progress made in stabilizing the ABI.

Doug Gregor and Ben Cohen recently discussed many of these features on a two-part episode of the Swift Unwrapped podcast. Check out the podcasts here: Part 1 and Part 2

The most code-affecting (by elimination, in the case of Equatable & Hashable!) bits are the progress on the generics front:

Swift 4.1 adds more generics features to the language, furthering the goals set out in the Swift Generics Manifesto. The following generics-related proposals have been implemented in this release:

SE-0143 Conditional Conformance
SE-0157 Support recursive constraints on associated types
SE-0185 Synthesizing Equatable and Hashable conformance
SE-0187 Introduce Sequence.compactMap(_:)
SE-0188 Make Standard Library Index Types Hashable
SE-0191 Eliminate IndexDistance from Collection

For more information about progress made with conditional conformance in Swift 4.1, check out this blog post

Do indeed check out that blog post,

Conditional Conformance in the Standard Library

The Swift 4.1 compiler brings the next phase of improvements from the roadmap for generics: conditional conformances.

This post will look at how this much-anticipated feature has been adopted in Swift’s standard library, and how it affects you and your code…

TL;DR: Things like Optionals and Arrays and Dictionaries will now be Equatable if their contents are, the way things should work!

More than TL;DR: Swift 4.1 conditional conformance is 💖AMAZING💖  and Conditional Conformance

Also, if you’d like more mapping smarts in JSONDecoder, there’s help with that:

JSONEncoder: Key strategies

The strategy enum allows developers to pick from common actions of converting to and from `snake_case` to the Swift-standard `camelCase`. The implementation is intentionally simple, because we want to make the rules predictable…

More discussion in Swift 4.1 improves Codable with keyDecodingStrategy

And the common nil-stripping application of flatMap is deprecated: Replacing flatMap With compactMap

If you‘re trying to hit a binary size target, this’ll help: Code Size Optimization Mode in Swift 4.1

That’s about it for things we’ve noticed of interest, but there’s another comprehensive roundup over at Chez Wenderlich in What’s New in Swift 4.1? — anything we missed here is no doubt in there!

UPDATES:

compactMap for Swift < 4.1

Behind-the scenes improvements in Swift 4.1

Forcing Compiler Errors in Swift

How to use conditional conformance in Swift

What’s new in Swift 4.1? and playground

What’s new in Swift 4.2? and playground

Ole Begemann’s Swift 4.1

What’s new in Swift? diffs any versions

Understanding protocol associated types and their constraints: “Swift 4.1 introduced the ability to make associated type constraints recursive: an associated type can be constrained so that it must also be of the same protocol…”

Delegate Strength Tip: No More Weakness

Now here’s a simple tip worthy of some signal boosting: If you had to pick the most annoying thing about modern Cocoa programming, that continues to regularly trip up even the best of the experts, what would you pick?

Yep, the weak-strong dance, that was our pick too. From the original @weakify and @strongify horrors through the currently conventional [weak-self]-guard-return boilerplate in Swift, it’s just distracting noise and all to easy to overlook with no help from the compiler in catching your retain cycles isn’t it?

Well, here is by far the most elegant solution to that problem we’ve ever seen!

Do you often forget [weak self]? Here’s a solution

You see, from an API design point of view, this new approach actually made things worse. Previously, the designer of an ImageDownloader API was responsible for not introducing any memory leaks to our app. Now, it’s an exclusive obligation of the API user.

And [weak self] is something that is incredibly easy to overlook. I’m more than sure that there is a lot of code out there (even in production) that suffers from this simple, but so ubiquitous problem … We can’t rely even on ourselves to write [weak self] in every part of our app (where needed), and we certainly cannot expect all our potential API users to do the same. As API designers, we need to care about safety at the point of use.

Exactly so!

Let’s look at the core of the problem: 99% of the time, when assigning a delegation callback, there should be a [weak self] capture list, but nothing is actually preventing ourselves from omitting it. No errors, no warnings, nothing. What if instead we could force the correct behavior?

Yes, that is, in fact, something we do want to force. And Messr. Dreyman has a remarkably concise and elegant solution to adopt:

public struct Delegated<Input, Output> {

private(set) var callback: ((Input) -> Output?)?

public mutating func delegate<Target: AnyObject>(to target: Target,
with callback: @escaping (Target, Input) -> Output) {
self.callback = { [weak target] input in
guard let target = target else { return nil }
return callback(target, input)
}
  }
}

and then you use like

self.downloader = ImageDownloader()
downloader.didDownload.delegate(to: self) { (self, image) in
self.currentImage = image
}

That’s a massive leap in safety for very little work, we’re going to adopt it immediately.

With handy accessors and conveniences to go along the library’s still under 50 lines of code — copy the code (or load it with your package manager of choice) from Delegated on github!

Universal Links: The Web-App Connection

Hmmm, looks like we’ve never got around to noticing Universal Links for Developers in this space before; the advantages of those, from Support Universal Links, are

  • Unique. Unlike custom URL schemes, universal links can’t be claimed by other apps, because they use standard HTTP or HTTPS links to your website.
  • Secure. When users install your app, iOS checks a file that you’ve uploaded to your web server to make sure that your website allows your app to open URLs on its behalf. Only you can create and upload this file, so the association of your website with your app is secure.
  • Flexible. Universal links work even when your app is not installed. When your app isn’t installed, tapping a link to your website opens the content in Safari, as users expect.
  • Simple. One URL works for both your website and your app.
  • Private. Other apps can communicate with your app without needing to know whether your app is installed.

Big step up from the custom URL stuff we last mentioned way back in URL Scheme Tidbits, isn’t that? Here’s a well worth reading article to bring us up to speed on some practical applications:

Techniques to Connect Websites to iOS Apps

First, what’s the end game here? To simply leverage some hosted .json files on your server and put meta tags in your markup to allow users to jump straight into your app or display information about it more effectively. That’s it.

This stuff is typically key for SaaS business’ or solopreneurs because in the world we live in, where there is a SaaS website a (hopefully) native app will follow. We want to help them dance together.

It helps that iOS 11 built features specifically for this. Open up your camera, point it at a QR code. Boom — iOS shows us the actionable details. Share a link in messages. Get a rich text preview. The list goes on…

QR code support? Yep, that comes for free with your apple-app-site-association file:

If you host such a file, the end result is that your app will immediately show to open via a notification when the user points at the QR code. The only metadata your QR code needs is the URL for your website.

No external QR code download, no more taps — nothing. It just happens.

If the user doesn’t have your app, Safari will kick in instead, taking them to your website…

… Safari handles all of this as well. If you hosted the QR code as an image, and an iOS user 3D touches on it — this exact same flows happens.

Yeah? Cool!

And if you haven’t looked into Shared Web Credentials for iOS 11 yet, that’s easy too, just associate your domains and tell the app where the credentials go:

This nifty trick is absolutely essential for you if your app has a log in mechanism or any user portal system online. By employing password autofill, users can tap on the lock icon in the quicktype bar that appears over the keyboard, authenticate and then have their information automatically filled out.

It’s beautiful, and I use it daily.

To allow for this to happen, there is minor housekeeping that you need to do for the text fields or text views representing your log in. Simply assign the correct values added in iOS 11 to their textContentType property…

… Once you throw that up on your site — the entire web credentials and password autofill pipeline is all set. I can’t tell you how much times this saves from a user perspective. It goes up by an order of magnitude if one uses Safari’s password suggestions as well.

Lastly, there’s tips on how to enrich your Messages sharing:

Sharing links within Messages is a ubiquitous practice among iOS users. Nothing is more rewarding than tapping on the link cards, with their inviting .png hero images sitting there beckoning us to load up a website within Safari.

Except when that doesn’t happen, and it’s just plain text 😬.

This is so easy to avoid, though, as you easily can control the title, icon, image and even video that displays. Using the open graph protocol, you can supply all of this stuff inside your site’s <head> tag…

The article finishes off by recapping Smart Banners in case you haven’t gotten around to those since iOS 6 either. That makes it a pretty much definitive resource for your app and website coordination — thoroughly recommend you go read and bookmark!

Promises, Promises, Knowing I’d Believe

And in Spot the 80s Lyric today, that post title is Naked Eyes providing the soundtrack for today’s post; we’re going to take a look at an interesting new library from Google named simply

promises

 

In general, a promise represents the eventual result of an asynchronous task, respectively the error reason when the task fails. Similar concepts are also called futures (see also wiki article: Futures and promises)…

Promises is a modern framework that implements the aforementioned synchronization construct in Swift and Objective-C.

Features

  • Simple: The framework has intuitive APIs that are well documented making it painless to integrate into new or existing code.
  • Interoperable: Supports both Objective-C and Swift. Promises that are created in Objective-C can be used in Swift and vice versa.
  • Lightweight: Has minimum overhead that achieves similar performance to GCD and completion handlers.
  • Flexible: Observer blocks can be dispatched on any thread or custom queue.
  • Safe: All promises and observer blocks are captured by GCD which helps avoid potential retain cycles.
  • Tested: The framework has 100% test coverage.

Benchmark
One of the biggest concerns for all frameworks is the overhead they add on top of the standard library (GCD in this case).

The data below was collected by running performance tests for Objective-C and Swift on an iPhone 6s iOS 11.2.1 for the popular frameworks: PromiseKit, BrightFutures, Hydra, RxSwift and plain GCD for comparison…

There’s a whole bunch of metrics collected there, this is the one we found most interesting:

Google Promises Benchmarks

So if you do have a need to mix Objective-C and Swift async code, promises looks like a pretty good option to consider!

However, these benchmarking comparisons aren’t going to mean very much in typical usage patterns, so you should probably go with whatever syntax feels most collegial, really.

Also, those benchmarks are probably not up to date with PromiseKit, which just updated:

PromiseKit 6 Released

With PromiseKit our then did multiple things, and we relied on Swift to infer the correct then from context. However with multiple line thens it would fail to do this, and instead of telling you that the situation was ambiguous it would invent some other error. Often the dreaded cannot convert T to AnyPromise. We have a troubleshooting guide to combat this but I believe in tools that just work, and when you spend 4 years waiting for Swift to fix the issue and Swift doesn’t fix the issue, what do you do? We chose to find a solution at the higher level.

So we split then into then, done and map.

  • then is fed the previous promise value and requires you return a promise.
  • done is fed the previous promise value and returns a Void promise (which is 80% of chain usage)
  • map is fed the previous promise value and requires you return a non-promise, ie. a value.

At first I was nervous about this. But with some use on real projects I quickly realized that done alone was making PromiseKit use much more pleasant. Because Swift has no inference to do about the return for done you can write many line closures without any pain. then and map still require you to specify the return types for closures if they are multiple line, but often they are single line because you are chaining promises encapsulated in other functions.

The result is a happier compiler, a happier you and also, pleasantly (and somewhat surprisingly), clearer intent for your chains.

There’s another recent release in this space that’s mostly under the radar so far but looks like it merits a close look as well:

Tomorrowland

It is loosely based on both PromiseKit and Hydra, with a few key distinctions:

  • It uses atomics internally instead of creating a separate DispatchQueue for each promise. This means it’s faster and uses fewer resources.
  • It provides full support for cancellable promises. PromiseKit supports detection of “cancelled” errors but has no way to request cancellation of a promise. Hydra supports cancelling a promise, but it can’t actually stop any work being done by the promise unless the promise body itself polls for the cancellation status (so e.g. a promise wrapping a network task can’t reasonably cancel the network task). Tomorrowland improves on this by allowing the promise body to observe the cancelled state, and allows linking cancellation of a child promise to its parent.
  • Its Obj-C support makes use of generics for improved type safety and better documentation.
  • Like Hydra but unlike PromiseKit, it provides a way to suppress a registered callback (e.g. because you don’t care about the result anymore and don’t want stale data affecting your UI). This is distinct from promise cancellation.
  • Tomorrowland promises are fully generic over the error type, whereas both PromiseKit and Hydra only support using Error as the error type. This may result in more typing to construct a promise but it allows for much more powerful error handling. Tomorrowland also has some affordances for working with promises that use Error as the error type.
  • Tomorrowland is fully thread-safe. I have no reason to believe PromiseKit isn’t, but (at the time of this writing) there are parts of Hydra that are incorrectly implemented in a non-thread-safe manner.

 

and here’s another:

Getting Started with Deferred

At Big Nerd Ranch, we have created a library called Deferred, which makes it easier for developers to work with data that is not yet available but will be at some point in the future. For example, when you’re downloading data from the network or parsing data, the data is not yet available because some work needs to be completed first. You might know this concept as Futures or Promises, but if not, don’t worry—this post will help you gain a better understanding…

…It was originally inspired by OCaml’s Deferred library.

And there’s a couple more mentioned in this excellent article on the subject,

Under the hood of Futures & Promises in Swift

So there’s a veritable plethora of abstractions to choose from.

Long as we’re on the topic of asynchronicity and all, here’s a good read on parallelization:

Parallel programming with Swift: Basics and Parallel programming with Swift: Operations

and a couple task libraries to take a look at:

Queuer

Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD).
It allows you to create any synchronous and asynchronous task easily, with just a few lines.

Here is the list of all the features:

  • Works on all Swift compatible platforms (even Linux *)
  • Easy to use
  • Well documented (100% documented)
  • Well tested (currently 99% code coverage)
  • Create an operation block
  • Create a single operation
  • Create chained operations
  • Manage a centralized queue
  • Create unlimited queue
  • Declare how many concurrent operation a queue can handle
  • Create a network request operation *
  • Create a network download operation *
  • Create a network upload operation *
  • Ability to restore uncompleted network operations *

ProcedureKit

A Swift framework inspired by WWDC 2015 Advanced NSOperations session. Previously known as Operations, developed by @danthorpe with a lot of help from our fantastic community…

And finally, here’s some lower level tidbits that are worth noting if you have challenges where you need to go right to the metal:

Friday Q&A 2017-10-27: Locks, Thread Safety, and Swift: 2017 Edition

Back in the dark ages of Swift 1, I wrote an article about locks and thread safety in Swift. The march of time has made it fairly obsolete, and reader Seth Willits suggested I update it for the modern age, so here it is!

Initializing on the main thread using dispatch_once without race conditions

We recently refactored the Khan Academy iOS app to use Core Data instead of the haphazard system of JSON files which we were previously using. In this post I’ll explain how to run initialization code that has to happen on the main thread without worrying about race conditions…

Leaky abstractions in Swift with DispatchQueue

At Q42 we have some apps with very occasional weird multi-threading issues. After a bunch of debugging Mathijs Kadijk and I figured out it had something to do with DispatchSpecificKey…

A Simple Approach to Thread-Safe Networking in iOS Apps

With our newfound understanding of URLSession‘s threading model, let’s sketch out how we might extend it to easily support running two requests in parallel. (The source code for this section is available on GitHub, ready for you to drop into a Playground.)…

UPDATES:

Understanding DispatchQueues

GCD Tips

Parallel programming with Swift: Promises

Summer of Code 2018

Well, here’s some news that’s interesting and also apropos to our Letter To A Young Developer from last time: 

  1. Are you a student developer? (If you’re not, but you know any, keep reading)
  2. Are you interested in an open source internship? (Correct answer is: YES)
  3. Are you interested in SWIFT? (If you’re not, ok wrong blog you may go now)

OK then, here’s an opportunity for you to jump on:

Google Summer of Code 2018

2018SummerOfCode

13,000+ STUDENTS, 108 COUNTRIES
13 YEARS, 608 OPEN SOURCE ORGANIZATIONS

33,000,000+ LINES OF CODE

Google Summer of Code is a global program focused on bringing more student developers into open source software development. Students work with an open source organization on a 3 month programming project during their break from school…

Which is an interesting opportunity every year yes, but this year is particularly interesting if you have designs on the Apple ecosystem:

Swift to participate in GSoC 2018!

I am thrilled to announced that Swift has been selected as a participating open source project in Google Summer of Code 2018!

…  Student applications start on March 12, 2018

The official application to GSoC starts on March 12. Before then, we encourage all prospective participates to socialize their ideas on the respective Development forum categories. Please tag all posts with the GSoC 2018 tag so that they are easily discoverable by others (e.g., students and mentors) interested in GSoC.

There are several open project ideas available on Swift.org — but potential projects do not need to be restricted to these ideas. Regardless if you are looking into working on a suggested project or one of your own creation, you are strongly encouraged to engage on the forums before applications are accepted to help shape your idea and ensure a good alignment with a mentor.

… Key Dates
March 12 (16:00 UTC) – Applications open
March 27 (16:00 UTC) – Deadline to file your application
April 23 (16:00 UTC) – Accepted student proposals are announced
May 14 – Coding begins

Personally, we think a particularly useful place to help out would be the Swift Package Manager, and if that sounds interesting here is your mentor:

So, student developers, if you haven’t got a firm résumé-enhancing plan already in place for the summer, we strongly recommend you give very serious thought to the Summer of Code in general, and making Swift better for us all in particular!

API 4 IAP PIA: SwiftyStoreKit Seriously Simplifies Subscriptions

There’s been quite a bit of angst and snark recently about what a pain in the fundament it is dealing with IAP subscriptions, you may have noticed:

Testing In-App Purchases Ruins Your Phone

Getting in-app purchases right is a goal that every app developer should have. Your customer’s experience when handing over their money should be seamless. To guarantee a good experience you must rigorously test. However, there are many pain points involved in doing this. Each individual issue is only irritating, but together they create enough friction that properly testing in-app purchases is a miserable experience…

My personal least favorite when working with recurring subscriptions: If you make a test purchase of a recurring subscription, you will be forever presented with a looping App Store login modal, usually when unlocking your phone. This renders any personal device you are testing on ruined… This is a common problem … which some people give short shrift:

My thoughts on the trending iOS subscriptions loop login complaints: read the documentation carefully and follow @Apple best practices. You’ll never encounter this problem.

Well … they’re not quite as clear as all that, really. Here is an excellent guide to the travails you’ll face:

Testing Auto-Renewable Subscriptions on iOS

Subscriptions work differently in TestFlight, the sandbox, and live on the App Store, so testing them requires knowledge of those differences. This is my attempt to help sort out the mess and document it for others to reference…

You definitely want to Read The Whole Thing™ on this one, but we’ll highlight this hack we did not know for testing live subscriptions on the App Store before release! No, really, you can do that:

For an app that has yet to be released on the App Store, getting an early version of the app approved is a great way to test subscriptions:

1. Submit a beta version of the app to App Review. Make sure to set “Version Release” to “Manually release this version” so that the app is not released on the App Store. 2. Generate promo codes for the app. This can be done for free apps that are approved, but not yet on the App Store. 3. Download the app from the App Store using a promo code. 4. Subscribe.

Since this app has gone through approval, subscriptions will perform exactly as they will when the app is live on the App Store, including charging testers who subscribe and allowing testers to manage the subscription in the App Store app. Promo codes can be given to testers so that they can test the app for free. Subscriptions paid for via promo code work exactly like paid subscriptions, except that they don’t auto-renew… Definitely want to make sure you do that. Surprises with your monetization are the worst kind of surprise, amirite?

Now, on the programming side, we feel there’s a clear best practice currently for implementing your StoreKit support in general, but particularly for subscriptions:

SwiftyStoreKit: “Lightweight In App Purchases Swift framework for iOS 8.0+, tvOS 9.0+ and macOS 10.10+”

SwiftyStoreKit Preview

Features:

  • Super easy to use block based API
  • Support for consumable, non-consumable in-app purchases
  • Support for free, auto renewable and non renewing subscriptions
  • Receipt verification
  • iOS, tvOS and macOS compatible

It’s been actively maintained up to 2 days ago as we write this, with 2733 stars on Github and 26,536 installs on CocoaPods.org — it’s healthy to be leery of introducing third party dependencies to essential parts of your app flow, but this one is downright mainstream at this point. And it comes with a complete background education:

Essential Reading

  • Apple – WWDC16, Session 702: Using Store Kit for In-app Purchases with Swift 3
  • Apple – TN2387: In-App Purchase Best Practices
  • Apple – TN2413: In-App Purchase FAQ (also see Cannot connect to iTunes Store)
  • Apple – TN2259: Adding In-App Purchase to Your Applications
  • iTunes Connect Developer Help – Workflow for configuring in-app purchases
  • Apple – About Receipt Validation
  • Apple – Receipt Validation Programming Guide
  • Apple – Validating Receipts Locally
  • Apple – Working with Subscriptions
  • Apple – Offering Subscriptions
  • Apple – Restoring Purchased Products
  • Apple – Testing In-App Purchase Products: includes info on duration of subscriptions in sandbox mode
  • objc.io – Receipt Validation

I have also written about building SwiftyStoreKit on Medium:

  • How I got 1000 ⭐ on my GitHub Project
  • Maintaining a Growing Open Source Project

So there you go, that should be all the resources you need for as painless an IAP implementation as possible!

And while we’re talking about IAP, there is a most excellent article here on design, psychology and strategy:

The Ultimate Guide To Mobile In-App Purchases Optimization

Now you can’t just create in-app purchases in your app haphazardly and let it run itself. It’s a long process that requires blood, sweet, and tears. You need to optimize your in-app purchases to make sure that you’re getting the most that you can out of them.

There are many different models, techniques, and strategies that the top-grossing apps and industry leaders use to optimize their in-app purchases and increase their revenue and we’ll be discussing all of the main and most popular ones… There’s not much here that will be completely new to you, especially if you play those pay-to-win games that have taken over the App Store these days; but it’s nice to have a concise compendium of best practices that’s up to date with iOS 11’s App Store IAP promotions to refer to. Our fave tip:

Purchases IRL

If your mobile app or game becomes big and popular enough, you can use that to offer real-life merchandise through your app. This had been the case with hit mobile games like Halfbrick’s Fruit Ninja and Jetpack Joyride that sell t-shirts and mugs through their games and Rovio’s Angry Birds that sells t-shirts, hats, toys, LEGO sets, backpacks, and more, and even went on to make an animated series and a full feature movie… That’s an interesting idea actually; if you have all this game art, why not make swag out of it? We do every so often get asked if we have shirts with the Trollsheep on them … maybe we’ll look into that. Especially now that we live in Southeast Asia and all where swag production is a thing!

UPDATES:

Apple Will Reject Your Subscription App if You Don’t Include This Disclosure iOS Subscription Groups Explained Castro 3’s Business Model

AppReceiptValidator: “Parse and validate App Store receipt files.”

iOS Introductory Prices

App Store Subscriptions And You 

IOS In-App Purchases and Subscriptions

iPhone X Notch-alance

Remember those innocent days a few short months ago when we all spotted the new safeAreaLayoutGuide and thought

Our constraints are now with the top and bottom anchors of the safe area layout guide. This is not a big change…

Oh, sweet naiveté. Did anybody actually call out in advance that subtle little change was foreshadowing THE NOTCHALYPSE? Yes, yes, every time something changes it brings out the fear and loathing no matter what it is, but the level of OMG NEVER BUY APPLE AGAIN … we saw this time, that was unprecedented. Personally, we think a phone with a bat-eared screen is kinda neat, but we’re weird. 

There’s a certain level of enthusiasm out there for clipping and masking and otherwise working around the new roundedness and notchedness … but we think Marco has it right here:

This is the new shape of the iPhone. As long as the notch is clearly present and of approximately these proportions, it’s unique, simple, and recognizable.

It’s probably not going to significantly change for a long time, and Apple needs to make sure that the entire world recognizes it as well as we could recognize previous iPhones.

That’s why Apple has made no effort to hide the notch in software, and why app developers are being told to embrace it in our designs…

So, we’ve got some rewriting to do in the next few weeks to have our apps fit nicely into The Brave New Notched World, and you probably do too we imagine; let’s see what resources are out there!

First off, go over the relevant stuff over at the mothership:

Building Apps for iPhone X

Designing for iPhone X

Updating Your App for iOS 11

Human Interface Guidelines — iPhone X 

Positioning Content Relative to the Safe Area

The great PaintCode people have updated their invaluable 

The Ultimate Guide To iPhone Resolutions

and also have specs for all the Notch attributes at

iPhone X Screen Demystified

More good reads on upgrading UI for the X at

Design for iPhone X

Supporting iPhone X

iPhone X: Designing for the Notch

iPhone X: Dealing with Home Indicator

UI Design for iPhone X: Bottom Elements

How iOS Apps Adapt to the iPhone X Screen Size — and the Adaptivity app showcased here looks like a good purchase!

Adaptivity is an app for developers and designers to visualize how iOS’s Size Classes and margins for layout and readable content look on real devices and how they change with respect to orientation, iPad Slide Over/Split View and Dynamic Type size changes…

Templates to help you out at

Apply Pixel’s iPhone X and iOS 11 UI Kit

iOS Design Kit’s Free iOS 11 GUI for Sketch

If you’re concerned with how your web sites will deal with the Notch, check out

Designing Websites for iPhone X 

Understanding the WebView Viewport in iOS 11

And let’s finish off with the niftiest idea we’ve seen for adapting in a non-approved way with the Notch:

ScrollSnake: “What if scroll bars on the iPhone X worked like the game “Snake”?”

UPDATES:

UI Design for iPhone X: Top Elements and the Notch

Designing for iPhone X: Guidelines to designing for iOS 11

Challenges of Supporting iPhone X

Fix for the missing network activity indicator on iPhone X

Validate My Experience

So we’re looking at updating one of our apps here for iOS 11 and joining the move to subscriptions which it appears is the only reasonable path to sustaining a productivity app on the horizon, so we’re seeing what’s new in receipt validation to support that, as last time we checked into it was four years ago and all and RMStore we picked then has languished since.

Let’s look around a bit … hmmm … hmmm … oh, what’s this? A comprehensive series walking through the whole process, updated for Swift 3? Well, bit late to the party, but looks like it’s all still relevant, and receipt validation code is something we really ought to write ourselves:

Preparing to Test Receipt Validation for iOS

After having to piece together each step along the path of preparing to test receipt validation for iOS apps, I’ve decided to combine everything into the following guide. Whether you’re working to implement receipt validation for a new iOS app, or for an existing one, this walk-through should provide guidance to get you ready to work with receipts in your iOS application…

Loading a Receipt for Validation with Swift

There are at least 5 steps to validate a receipt, as the Receipt Validation Programming Guide outlines…

Extracting a PKCS7 Container for Receipt Validation with Swift

Before attempting to work with OpenSSL’s PKCS7 functions, you’ve got to do a little prep work to get the functions to play nicely with Swift. Unfortunately, Swift doesn’t work well with C union types. It simply can’t see things defined with a C union…

Receipt Validation – Verifying a Receipt Signature in Swift

The aim of this guide is to help you take a look inside the PKCS #7 container, and verify the presence and authenticity of the signature on the receipt…

Receipt Validation – Parse and Decode a Receipt with Swift

The aim of this guide is to help you parse a receipt and decode it so that you have readable pieces of metadata to inspect and finalize all of the receipt validation steps…

Finalizing Receipt Validation in Swift – Computing a GUID Hash

After finishing this guide, you’ll simply need to use the parsed receipt data to perform any app-specific enabling/disabling of features based on the data within a valid receipt. If the receipt is invalid, you’ll need to handle that as well. But all of the relatively difficult work of working with the Open SSL crypto library will be DONE after this guide….

… The bottom line is that from this point on, you no longer need Open SSL or any additional cryptic, low-level, unsafe pointer-type stuff to finish things out. I hope this series has been helpful in setting you up to validate receipts locally on a user’s device!

That … is a veritably monumental guide to the validation process. And conveniently finished up right when we need it too, thanks ever so much @andrewcbancroft!

UPDATE:

We just beat by a day Messr. Bancroft pulling together his own collection guide, now that you’ve read ours go to the real thing!

Local Receipt Validation for iOS in Swift From Start to Finish

and code at SwiftyLocalReceiptValidator!

RELATED UPDATES:

InAppPurchase – A Simple Swift Library For In-App Purchases With Support For iOS 11’s Promotion Features

YapDatabase: Ditch Core Data

The choice of database technology for our apps has been something of a question for us the last while, where by “last while” we mean since iCloud Core Data was deprecated, which miffed us no end since we’d rather like our apps’ initial releases to Just Work™ across devices for iOS users without jumping through any great hoops or introducing any dependencies on non-Apple services.

So let’s see what’s new in Core Data this year in the iOS 11 release notes! Errr… nothing?

Hmmm. Let’s check out the What’s New In Core Data WWDC 2017 session

kinda thin, don’t you think?

Hmmm, hmmm. Sorta looking like it’s time to seriously evaluate other alternatives, it is.

We liked the looks of RocketData, very Swifty and all, but it … appears to be languishing.

Soooooo, what to do? Well, here is an article that presents an alternative of interest:

Ditching Core Data

I have been using Core Data since iOS 3.0. With few exceptions, it has served entirely as a network cache. Take data from a network response, turn it into a set of objects, save those objects, and update the user interface. Rinse and repeat.

The stack is pretty simple. A set of nested contexts to keep object building off of the main thread, a couple of models that have init(dictionary: NSDictionary), and some find-or-create helpers can get you a long way. The problem is that the apparent simplicity comes with an incredible amount of baggage. Instability, buggy classes, and outdated APIs make building modern apps difficult.

As a community, we have tried to solve these problems by building wrappers around Core Data. These wrappers add their own issues and none of them hide the fact that Core Data was simply not meant to be used like this…

Nodding along here? Yep, us too.

After some research and planning, I landed on a set of features that I wanted in a persistence framework. The list is pretty short:

  • My objects must be plain objects. Requiring model objects to extend a certain base class is painful; especially when you cannot see the source for those classes. I want to know that I can create objects however I like, use them wherever I like, and build my own functionality around them without worrying about what sandbox they belong to.
  • I should not have to worry about concurrency. Tools like closures, Grand Central Dispatch, and NSOperationQueue make it easy to write code that spans many threads. Unpacking objects on background threads that are later used to update interface elements is a common operation that should be simple and easy to reason about.
  • I should not have to write migration code. Frameworks and libraries can and should be smarter than this. Let me describe how I want the database to look. You take care of the rest.
  • I should be able to track and respond to atomic changes. Elements in my application should be able to reload themselves if a single object, or a collection of objects changes. Otherwise it may spend too much time updating things that may not need to be updated, which could have a negative impact on the user experience.

Sounds good. Only thing we’d add as a base requirement is “CloudKit sync” to make the cross-device experience seamless.

And the winner was:

I decided to use YapDatabase. It came highly recommended and it offers support for all of my requirements. YapDatabase is, at its core, a key-value store build on top of SQLite. It has a simple API and is incredibly flexible…

You will notice a few things about my model objects right away: they are completely immutable, they have no knowledge of the persistent store, and no magic superclass. These objects can be passed around the application (and across thread boundaries) without requiring knowledge of the database or how these objects are to be handled…

All database operations in YapDatabase are handled through database connections. YapDatabaseConnection has functions for reading from, writing to, and responding to individual changes in the database. It does all of this in a thread safe manner. One less thing to worry about!

OK, flipping down the feature list there, looks like a solid solution to entry level needs, got a track record and is being easily maintained, just that one little extra base requirement…

• Sync. Support for syncing with Apple’s CloudKit is available out of the box. There’s even a fully functioning example project that demonstrates writing a syncing Todo app.

… well, there we go then. Unless some dramatically superior alternative comes to our attention, next data-storing app we ship will use YapDatabase too, farewell Core Data!