Category Archives: iPhone

Ad Attribution comes to iOS apps and the App Store

I have not heard a lot of hoopla about this, but I think this is a big deal. Back in 2019, WebKit announced a way to do ad attribution without per-user tracking. I put support for this in the AppStore on my WWDC 2019 wishlist.

The WebKit team just announced a privacy preserving ad attribution system for websites. I want the same thing to work for an ad for an app that appears on the web, App Store, or in another App. No need to attribute to a user — just the ad source is sufficient.

I explained in a followup:

The last few years have been a cat-and-mouse game between Ad Tech firms finding loopholes in iOS (e.g. shared Pasteboards) and Apple closing them. It would be much better if Apple provided a privacy preserving mechanism and then explicitly forbade anything else in the developer agreement.

I put this on my 2021 wishlist as well.

I just noticed this video on the WWDC Site: Meet privacy-preserving ad attribution, which appears to have done just that.

I don’t personally need this feature, but we need to do something to help out app developers who are under pressure to get some kind of ad effectiveness data. With IDFA basically gone, Ad Tech firms are going to resort to fabricating their own ID from whatever identifying information they can grab.

One thing to remember is that none of these firms have any kind of relationship with Apple. They are not parties to the developer agreement, so they have no obligation to follow it. It’s the developers that integrate their SDKs that take the risk and are the ones violating the agreement.

Another risk is that these SDKs inherit all of the permissions their host app has obtained. So, you could ask for location for a very good reason (e.g. you show the weather) and they could see that they have the permission and use it for something else (e.g. enriching their ad targeting database). Again, your app probably didn’t disclose this, but those SDKs don’t need to follow the rules—only you do.

So, I’m looking forward to this ad attribution method being adopted widely and for app integration to be done by the app developer just making HTTPS calls, not integrating an SDK. It may be too much to hope for, but it did require Apple to take the first step and offer a mechanism, which they now have.

WWDC 2021: Day 2 Thoughts

I watched a few sessions, mostly the overview ones.

watchOS

I’m even more excited by the always-on screen for apps. Workout apps, like Sprint-o-Mat, will be able to update the screen every second while running a workout session. This is good enough for me. They also let you know (via a SwiftUI modifier) that the screen is in the dimmed state, so you can reduce detail and focus on the most important parts of your interface.

There is also a Canvas in SwiftUI for watchOS now. Right now, the main view for Sprint-o-Mat uses stretched Circles to draw the progress rings. I did this because SwiftUI does not support elliptical arcs. I will have to check to see if Canvas is more powerful.

I also missed that unit tests work for watchOS targets in the latest Xcode. I currently keep testable code in a swift package so I can test it.

Swift

I hope that the improved type inference speed really works. I run into problems with this for even fairly simple code (where Swift just gives up and you need to rewrite it to be more explicit).

I also was unaware of Swift Numerics, which is nice. What I really want is something like a DataFrame, like Pandas, but this is a foundational step. I still use python as my “go to” for when I need something one step past a spreadsheet, even if I don’t need these features because I know they will be there if I need them.

One small thing that makes my life easier is that CGFloat and Double will automatically convert without an explicit cast. I write a lot of SpriteKit tutorials on App-o-Mat, and I like to keep the code super-simple.

And of course, async/await, will make lots of code better. I use it all of the time in Typescript, and I am looking forward to adopting it. Sprint-o-Mat is extremely asynchronous and I mostly solve its complexity with Combine today.

Speaking of Combine, I was somewhat surprised to see no mention at all so far, so I don’t think we’ll see more adoption in the frameworks this year.

WWDC 2021: Day 1 Thoughts

So far I’ve watched the Keynote and the Platforms State of the Union.

watchOS

The biggest thing to me was that a wishlist item I had this year and last year was finally done: watchOS apps will keep the screen on, not just show a blurred view with the current time. I had only asked for this for workout apps while doing a workout, but they are just doing it always, which is great.

They reworked the Breathe app, so I hope that they allow meditations more than 5 minutes. Also, I kind of want Tai Chi to log mindfulness minutes instead of workout minutes.

Swift Concurrency

Swift first class concurrency support is obviously great, but since Swift is open-source, we’ve known about this coming for quite a while. They seemed to have implemented it much like it’s implemented in other languages. I’ve been doing a lot of Typescript this year, and it seems basically the same.

They have also done a few important things related to this.

  1. If your asynchronous function returns a Result with a non-Never error type, they will automatically turn that into an exception.
  2. They provided async compatible versions of asynchronous APIs throughout their frameworks.

Focus

I am very much looking forward to the various Focus modes. I’m not sure that the new APIs will result in anything I want, but I am interested in innovation here.

Xcode Cloud

Xcode cloud isn’t going to be out for a while, but I signed up for the beta. My personal usage will depend on cost. I am using GitHub workflows for a new open-source swift framework I am building. In the past, I have used Microsoft’s App Center. Apple’s ability to provide cloud services to developers is mixed.

Things that are part of the app runtime, like notifications and CloudKit are excellent. They are reliable and fast. But, AppStoreConnect, the dev portal, and things like that are a mess.

If Xcode Cloud is considered mission critical and treated like notification delivery, then it will be great. But, I do suspect it’s more likely to be like AppStoreConnect (and I’m just talking about speed and reliability here — not the other pain points).

Face Time Data Channel

As part of the new Face Time improvements, they added an API to sharing data in a group to be used however the app wants. The demo was a shared whiteboard. I think this will be interesting beyond the obvious applications for streaming apps and games.

Random Stuff

There were a bunch of other random things that seem interesting.

  1. iCloud+ seems to come with a VPN now
  2. All the RealityKit stuff seems great — especially the object capture
  3. Playgrounds being able to make and deploy apps is great, but I don’t think this is for professionals.
  4. Multitasking menu on iPad will finally make this usable. This is the only thing that makes me want to update my OS immediately.
  5. Hoping on-device Siri works well, but my problems are with Siri just never responds sometimes (mostly music requests while out for a run).

NERD Summit 2021

The NERD Summit is going to be virtual again this year. It’s the weekend of March 19-21. There are tons of great sessions for beginners, so if you want to get into programming, you should take a look.

I spoke at the conference in 2017 about how to practice iOS development. As part of the talk, I open-sourced an app that could be used for conferences, which I forked into the conference app for NERD Summit. You can download it here (it’s been updated for 2021).

The source code for the conference app is on GitHub. Feel free to fork it for your conference. It’s easy to adapt — it uses a couple of google sheets as a data-source, so if you update the URLs to sheets in your account (make them publicly readable), you can show your conference events instead.

Programming Tutorials Need to Pick a Type of Learner

I’m working on an app to help me stay on an intermittent fasting routine. I wrote about it a little in Icon-first Development.

Fast-o-Mat is an iPhone app, but I want an Apple Watch complication to give me quick access to when my fast begins or ends. To do that, I need to get data from the phone to the watch.

I had never done this before, and I didn’t have the first idea of how it is done in modern iOS/watchOS development.

Here was my process

  1. Do a few google searches to find out the basics. I learn that this is called Watch Connectivity.
  2. Try to make sure that this is the modern way of doing things, since Apple changes things a lot and watch development generally change a lot in 2019. It is.
  3. Look for a tutorial. I pick this Hacking With Swift one because they are usually pretty good. (Here is Part II, the Watch app, if you need it)

Then, at this point, all I do is look for the import and the basic classes I need and see how far I get from just basic iOS knowledge.

This tutorial is good at facilitating that.

  1. The code samples are easy to skim for
  2. There isn’t much pre-amble before we start getting into it
  3. It’s focussed on just the code we need for Watch Connectivity

So, this is very unlike my idea for vague tutorials, but I am not really a new learner.

There isn’t a new concept here for me to learn on my own—I understand the concept of asynchronous message sending. I just need to know what framework and classes to use for this specific task.

The issue is that this same tutorial is what a new learner would find as well.

I believe a they would get this all working by following the instructions step-by-step, but would they have learned it beyond that? Could they troubleshoot?

One thing that is not clear from the API or this tutorial is that Any doesn’t really mean Any in the message parameter to sendMessage

func sendMessage(_ message: [String : Any], replyHandler: (([String : Any]) -> Void)?, errorHandler: ((Error) -> Void)? = nil)

I decided to just use one of my types there. It’s a struct with two TimeInterval parameters.

The documentation says

A dictionary of property list values that you want to send. You define the contents of the dictionary that your counterpart supports. This parameter must not be nil.

And running it says:

errorHandler: NO with WCErrorCodePayloadUnsupportedTypes

And now I see that “property list” values are things that you can store in a plist (so, not my struct, just simple types or NSArray or NSDictionary). And yada yada yada, it’s a little more complicated when you want to do this for real.

This is all to say, sometimes you just want the code (like me) and sometimes you are trying to learn a new concept from first principles, and the same tutorial can’t deliver both (or should even try).

New Article in the Swift Companion: Methods

Yesterday, I wrote that books should get you to write code, not just read it. I’ve been working on a companion to Apple’s Swift Programming Language book that helps you do that by offering exercises for each chapter.

I just published the companion to the Methods chapter on App-o-Mat. If you want to start from the beginning, go to the outline of Section 1. If you understand the content of the corresponding chapter, the exercises are meant to be very easy. If you are having trouble with them, it would be a good idea to review the chapter again before moving on.

Playing a Book

I’ve been thinking a lot about what books are for. Specifically, non-fiction books, and more specifically programming books. I’ve finally figured out how to describe what I’ve been thinking: You don’t read a programming book, you play one.

I mean play, like playing a game. In a game, you progress through levels by learning and applying skills. At the end of the level, you play against a boss that you have to beat to progress.

In books, you progress through chapters. But, there is nothing that stops you from just reading and reading and reading and well, not learning or applying anything. At the end of a chapter, you can just turn the page and keep going.

Over on App-o-Mat, an iOS content site I maintain, I’ve been working off and on a companion to the The Swift Programming Language book by Apple. I started the companion on Dev.to with a short section on how to read the book, where I said you should it read it side-by-side with an Xcode Playground page open. That you should not copy any code into it, but type code as you learn it. Get used to typing code.

Then, for each chapter, I offer some simple exercises that let you know that you understood the chapter.

I now realize that I was turning chapters into levels with bosses, which make The Swift Programming Language a book you can play.

WWDC 2020 Wishlist – Xcode / Swift

Yesterday I posted my watchOS WWDC wishlist, which is driven by what I am seeing in building Sprint-o-Mat.

I recently started working with Typescript and VSCode on an open-source project that needs a Swift and TypeScript version of the same functionality. I wrote a Swift version, and then did a very faithful (almost line-by-line) port to Typescript, which I did not know at all before starting. I never used VSCode (or Atom) before starting.

Microsoft makes excellent developer tools.

My project is admittedly very small, but luckily I can see how it works with with a large project because a minimal React site with Typescript has 48k files of dependencies. VSCode has nearly instantaneous code-completion and real-time error reporting. A minimal app in Xcode isn’t nearly as fast or reliable.

The combination of VSCode and Typescript makes Xcode and Swift look a decade behind. It’s comparable to Apple’s lead in chip design and the advantage that gives to its products — that’s the kind of lead Microsoft has in developer tools. Luckily for Apple, that advantage mainly flows to in-browser and server-side development, where Swift has effectively no usage.

Xcode / Swift Wishlist

  1. Make Xcode reliable and fast
  2. Make Swift compilation reliable and fast
  3. Make Swift type inference flow knowledge about values into conditionals. Here’s a simple example:

    let x = (anOptional != nil) ? funcExpectingNonNil(anOptional) : fallback

    We (and Typescript) know that anOptional is not nil in the call to funcExpectingNonNil, but Swift does not.

WWDC 2020 Wishlist – watchOS

Like previous years, my wishlist is highly influenced by what I’m working on and is not a prediction — just stuff I have needed in the past year.

I Just released a new watchOS app, Sprint-o-Mat that helps me in outdoor running workouts. I had actually started it before WWDC 2019, but completely started over to do it as an independent watch app on SwiftUI.

Here’s what I’d like from watchOS

Allow the user to control location privacy in the watch’s settings app
You can already control HealthKit authorizations on the watch, but changing location authorization makes you use the iPhone. This is impossible to link to, and very hard to explain.

Make some SwiftUI equivalent to WKInterfaceTimer
This view is what makes showing a timer easy and performant. You can update it with elapsed time at a low frequency, but it updates its view in between so that it looks like a running timer.

Unfortunately, you can’t even host WKInterfaceTimer in a SwiftUI View (via interop) because it doesn’t have a default init (and can only be constructed via a Storyboard)

Allow workout apps to keep showing on the display when a workout is running
When you run the built-in Workouts app, the display stays on and shows the UI of the app. For 3rd party workout apps, when you lower your wrist, the display shows the time and a frozen UI under a blurred overlay.

This means that 3rd party workout apps require the pre-always-on wrist movements if you want to see their updated UI.

Add the APIs that the Workouts app uses to send data to the Activity app
The built-in Workouts app appears to have private APIs (or private metadata) that the Activity app uses to enhance the workout display (e.g. custom icons, per-segment data). I’d like to see those, and even new ones, publicly available to any workout app.

Make some canonical way to base font-sizes on display size
There isn’t a good way that I can see to make a single View for 38mm and 44mm watches that look good without hardcoding or hacks.

There are a lot of other issues that I ran into, but the general idea of an independent watch app coupled with SwiftUI and the simplified app architecture more than makes up for it. If Apple just keeps moving this forward in big steps, I’ll be pretty happy.