Category Archives: Software Development

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.

Thoughts on async / await in Swift

This is the latest in a series of major language changes that Apple has introduced, going back to ARC in Objective-C. It feels like this one has been a long time coming, but the implementation is thorough and satisfying.

One thing I appreciate is that they revisit framework APIs to offer up modern versions simultaneous with the new language feature. They did the same for blocks and exceptions when they were introduced. One reason they are able to do this is because the APIs are very consistent, and it’s possible to do a mechanical translation.

And even though Objective-C won’t get async/await, the compiler will recognize common asynchronous function signature patterns and offer up async versions in the generated Swift interface.

Another thing that struck me is the deep compiler integration to flag common concurrency bugs. For example, you can’t capture mutable variables by default, so you need to do something to make them safe to use. The common answer will be the new actor concept.

I was somewhat surprised that the various task constructs (async and asyncDetached) and groups were a little more complex that I thought would be coming (I’m not following Swift Evolution very closely). But, the presentations offer good motivation for when you might use them. It also seems like you can start simple and use the more manual mechanisms if you need them.

I’ll see how it goes as I adopt these in Sprint-o-Mat.

TDD Video

This video from Ian Cooper on what happened to TDD has reinvigorated my usage of TDD

https://www.youtube.com/watch?v=EZ05e7EMOLM&list=PLEcwzBXTPUE9V1o8mZdC9tNnRZaTgI-1P&index=9

Ian completely explains what happens to long projects with a lot of tests and describes how to avoid the ossification that comes from tests coupled to the implementation of the code it tests.

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).

WWDC 2021 iOS Development Wishlist

WWDC starts tomorrow. Here is what I want in iOS development. Most of these probably apply to all of the platforms, so I mean this as the more as the frameworks that are on all of Apple’s OS’s.

  • Provide Combine interfaces for all frameworks. Or at least something more natural for SwiftUI. This would include at least CoreLocation, HealthKit, and CoreData. It would be nice to have an RxCocoa style interface to UIKit, but I think that’s probably not on their radar.
  • I’m not sure what would make screen navigation easier to understand in SwiftUI, but what we have now doesn’t seem right.
  • It would be nice if Apple had first party support for an anonymous way to track a link to the AppStore to an installation and run of an app. This is something in Safari already (ad click attribution for the web). And then, make this the only allowed way to do this.

This isn’t a developer ask, but I would love Apple to provide a pasteboard manager for iOS. These are common on macOS, but the privacy model of iOS precludes third-party implementations. Even if it was just in iPadOS, it would go a long way to making iPads more usable for more complex work. I don’t think it would desirable on iOS to make APIs that would make it possible for a third-party to make one.

Dependency Based Tech Debt

One of the things I am doing right now is ripping Bootstrap out of App-o-Mat. The site was mostly built in 2013 and at the time, Bootstrap was good about hiding all the float/clear/positioning nonsense from CSS and giving you a simple grid system. Once I had it, I used everything else it brought along. The site markup is pretty coupled to Bootstrap.

My plan is to build it on just a very small amount of hand-written CSS. Modern CSS has flex and grid layouts built-in, and so re-implementing what Bootstrap offered for layout is not that hard (especially for my limited usage).

When I’m done, my only frontend dependency will be on highlight.js, which syntax colors my code samples.

Ripping out dependencies is a recurring theme for me when a codebase starts to age. I wrote about this in Tech Debt Happens to You.

And I think that this is the main source of tech debt, not intentional debt that you take on or the debt you accumulate from cutting corners due to time constraints. The debt that comes with dependency and environment changes.

Being able to bring code into your project or build on a framework is probably the only thing that makes modern programming possible, but like mortgages, they come with constant interest payments and a looming balloon payment at some point. 

There are some you can’t avoid, like the OS, language, and probably database, but as you go down the dependency list, remember to factor in the debt they inevitably bring with them.

Of course, in 2013, the trade-off was probably right for me. I really didn’t want to build anything complex with CSS as it existed. Today, I be hard-pressed to take on any CSS framework dependency (I looked at Tailwind).

It’s not that they aren’t useful—it’s that I don’t have time to keep up with the dependency management problem they will bring with them, and they don’t promise any kind of long-term backwards compatibility (like SQLite does, for example).

WWDC 2021 Developer Tools Wishlist

WWDC 2021 starts Monday. Here are some of the things I hope to see with the developer tooling.

Xcode

  • Playgrounds are still super-buggy. I get red-squiggles and false errors everywhere in source files.
  • Ditto with SwiftUI previews. Even for simple stuff, I constantly need to reset them.

Swift

  • Support for narrowing, like in Typescript. With narrowing, your conditionals are taken into account when checking for the correctness of your code. So if you check is something is not-nil, then inside the if block, I can use it. This is better than an if let, because that creates a new constant and you cannot modify the obj using it. There are also more complex possibilities that are not possible with if-let.
  • Compilation speed.

I write Typescript in VSCode which is a freaking Electron app and it smokes Xcode with Swift.

It checks for errors as you type and it’s fast, never wrong, and always works. Typescript is also a type-inferring language and JSX is similar enough in spirit to SwiftUI. I have no idea why Microsoft can do this and Apple cannot.

WWDC 2021 watchOS Wishlist

WWDC 2021 starts Monday. Here’s what I’m hoping to see that would help me with Sprint-o-Mat.

  • Third-party workout apps should be able to keep the screen live, like the built-in app does. It’s a pain to do workouts and see blurred screens, especially for apps like meditation or yoga where you might not be able to easily move your wrist. Even with my app, I constantly see blurred screens during my run and have to shake my wrist to see my progress.
  • The Activity app has bugs with showing third-party workouts. There seem to be undocumented data types that the real Workouts app is able to write, and segments don’t work at all.
  • There are still a bunch of kinks with regards to independent watch apps. For example, users control HealthKit permissions on the watch, but location on the phone.
  • There is still no way to use the built-in timer controls with SwiftUI. They are built to be battery efficient, so making them available makes it easier to keep the screen live.

This list is pretty similar to last year because they didn’t address any of these. The first one would be good for all workout apps, so I really hope they do it this year.

Learn by Cloning

The App-o-Mat website was mostly written in 2013. The backend is in Django, and over time I have had to constantly upgrade that, so now it’s on pretty modern Django and Python 3.

The frontend is simple HTML, but uses Bootstrap and a bootstrap template for layout and styling. I decided it was time to abandon that and just build it on CSS Flex and Grid. The styling isn’t complex, so I can easily write the CSS for that.

I found this YouTube video to be a great whirlwind tour to implementing a design in modern CSS.

He mostly just plows along and does it, which was good enough for me.

In my version, I am learning from the lessons of Tailwind and relying nearly 100% on utility classes (or by selecting tags classlessly), so that I can do everything I need from the markup and inside server-side components. I would use Tailwind, but it’s overkill for my system, and I am sick of updating dependencies for this site.

In the end, the site should be pretty much the same, except with no Bootstrap and fairly simple CSS that I can maintain going forward.