Blockstack on iOS Constraints

I did some investigation on iOS to understand what types of constraints we are operating under on the platform. I also created a demo application.

The challenge

iOS has restrictions on what can run in the background and for how long. Because of these, we can’t install a Blockstack Core API node that’s always running on iOS like we do on desktop platforms.

The questions

On iOS:

  1. Can we run a web server? Yes
  2. Can we access that web server from our own app? Yes
  3. Can we access that web server from another app? Yes, but only for a limited amount of time.

Demo

We can:

  1. Start a webserver on an iOS device (to provide Blockstack API and/or the Portal)
  2. Access that web server for as long as we want through a webview running in our app.
  3. Access that web server from other applications on the device for a period of time while the app is in the background.
  4. Keep the server running for a period of time after the app goes into the background. On both my iPhone 7 plus running 10.3 and the iOS simulator bundled with Xcode 8.3, that time is approximately ~175 seconds. It may be significantly less on older devices and can be cut short by the operating system for various reasons. (eg. low memory, low battery)

Some screenshots:

User Interface

In this demo, I am using a SFSafariViewController. The benefit of this component is that it has access to everything that Safari has access to: the user’s cookies, local storage, etc. The downside (from our perspective) is that we can’t do anything with its interface.

Using WKWebView would allow us to customize the interface (we could remove the localhost @guylepage3 :smiley: ) and experience at the expense of losing access to shared cookies, local storage, etc from Safari. We’d only want Blockstack Web Apps running in our app anyways (so that they can always access the Core API), so this is probably an acceptable trade off.

Syncing data with native apps

Since we can’t provide a Blockstack Core API endpoint that’s always available, accessing storage is a challenge for native apps.

Let’s examine different scenarios and some possible approaches:

Storing data when the Blockstack app is running in background

Apps should be able to access the Blockstack API as normal during the time the Blockstack App is active in the background.

Storing data when the Blockstack app is NOT running in the background

I see two approaches to this:

1. Explicit user initiated storage

  1. Native app redirects the user (using a custom URI scheme handler) to the Blockstack iOS app
  2. Blockstack iOS app starts the API
  3. Blockstack iOS send the user back to original app (again using a custom URL scheme handler registered by the app)
  4. App writes data to the API

2. Background storage

  1. Native app sends an api request indicating that it would like to save some data to an endpoint run by Blockstack Inc. (Centralization!)
  2. Endpoint sends a silent Apple Push Notification to the Blockstack iOS app.
  3. Blockstack iOS app is woken up by iOS when it receives the notification and has a short period of time where it can run in the background (anecdotally ~30 seconds). During this period, it could start the API.
  4. Native app polls periodically for the Blockstack API to start. When it starts, the app writes data to the API.

This background storage method is predicated on the iOS app having the remote notification and background fetch capabilities:

It also requires users not to disable Background App Refresh.

Background refresh is toggled in Settings -> General -> Background App Refresh

Summary

I think the situation on mobile, at least for iOS, is very positive.

We can offer the full Blockstack experience for web apps as long as we load them in our built-in browser with little change from apps running in desktop browsers.

We can offer native apps most of the Blockstack experience with a bit of additional work required on storage and some constraints on size and the amount of time an app can spend writing its data to the API.

We might even be able to solve the problem of an API that is only periodically available by putting the logic for handling offline (unreachable) storage in our client libraries instead of behind the Core API.

Thoughts Team @Blockstack?

2 Likes

This is something I’ve been looking into for months. There are couple of problems that go beyond “what’s possible” to do in the technical side. If you want to distribute apps on the App Store that are going to be designed this way, brace yourself for rejection. A while ago, while I was at the Blockstack office in SoHo, I was contemplating a case where a silent push notification would “wake up the app” for a bit to keep it working. This would be an immediate violation of the 4.5.4 clause in The App Store Review Guidelines document that reads:

4.5.4 Push Notifications must not be required for the app to function, and should not be used for advertising, promotions, or direct marketing purposes or to send sensitive personal or confidential information.

And there’s also another problem that would violate the terms:

2.5.2 Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code, including other iOS, watchOS, macOS, or tvOS apps.

I still haven’t found a way to be App Store compliant, and to be honest, I’m not a fan of jailbreaking devices and distributing apps through other sources. The approach of having richer client libraries and APIs would be the optimal case for fully supporting native iOS.

The point is that, again, just packaging a “web app” on a web view or using the Safari controller would also violate clause 4.2.

4.2 Minimum Functionality
Your app should include features, content, and UI that elevate it beyond a repackaged website. If your app is not particularly useful, unique, or “app-like,” it doesn’t belong on the App Store. If your App doesn’t provide some sort of lasting entertainment value, or is just plain creepy, it may not be accepted. Apps that are simply a song or movie should be submitted to the iTunes store. Apps that are simply a book or game guide should be submitted to the iBooks Store.

Special attention to Your app should include features, content, and UI that elevate it beyond a repackaged website. should be given because I’ve seen this happening countless times. Apple hates hates them and it’s very easy for them to detect them using their automated tools that analyze app bundles.

App Store Review Guidelines Document

1 Like

So happy to see you here again @itsProf! Thanks for commenting!

Push notifications wouldn’t to be required for the app to function.

The idea would be that if the user enabled them, then apps could use them to avoid prompting the user to save his data to the Blockstack iOS app.

This is probably a bigger problem. Native apps that want to use Blockstack functionality can’t depend on the Blockstack iOS app being installed. They’d have to work even if Blockstack for iOS wasn’t installed.

It’s pretty easy to understand Apple’s thinking behind this. They don’t want someone to download Acme App and have it nag them to go download Blockstack for iOS before it will work. That would be a throw back to the DOS/Windows days where you games wouldn’t run unless the user had the right graphics and sound drivers installed.

1 Like

I think Apple will look at this as a sketchy work around. One of the things we’ve witnessed with Apple is that their guidelines are subjective as well. If you try to fool them with a work around that they deem to be not very useful, like bouncing a user to and from a native app to the mobile web, they will just reject it based upon a terrible ux.

Our iOS app would be a:

  • browser for the decentralized internet
  • identity manager
  • bitcoin wallet
  • search tool for profiles
  • storage management tool
  • authentication tool

In your view, would that functionality fail to satisfy the 4.2 minimum functionality clause?

Many iOS apps implement portions or all of the interfaces with webviews. HSBC’s mobile banking app is a good example of one that does this.

A repackaged website would be if we made an iOS app that loaded https://blockstack.org in a webview. It wouldn’t feel app-like and it wouldn’t add any value compared to the user opening it in Safari.

My question is…

Is there a way to talk directly with Apple on this so that we may provide users with the most optimal experience? They may be more inclined to partnering with the Blockstack open source community and allow us to utilize the push notification method. Then again, maybe not… :thinking:

Ideally, what I was picturing is a way to have a Blockstack node explorer, have the user choose the one he/she wants to use and configure the native API clients to point to those instances instead of attempting to have a Blockstack iOS instance running on a web server running inside the device (as I mentioned before, it will violate Apple terms). The user might even host their own instance wherever they want and have them input the necessary parameters for the app to use it. The exception would be to run it inside their own devices. I’ve been waiting to have more API’s exposed as REST methods to make this happen and I honestly don’t know if there are plans to support this. If so, it will make native Blockstack iOS apps a reality. Any thoughts @Blockstack?

I don’t think that Apple will be open to support an app architecture like this in the future.

1 Like

But the browser in the end will render everything inside web view and the apps would be entirely web-based. I’ve seen apps made this way submitted and getting rejected because in none of the UI uses UIKit.

Agree that there is this risk.

How would the user experience work?

  1. download native app
  2. select Blockstack API node ?

Running a web server doesn’t violate their terms - there are multiple apps that run web servers in the app store.

I agree - they probably don’t want apps interacting like this.

There are plenty of web browser apps in the app store - both the well-known ones such as Chrome and Firefox (using Webkit of course ;-)) and a number of…umm…less well-known ones (was surprised how many there are these days!)

We would definitely want to use UIKit to make it feel native. (Even though @guylepage3 's CSS ninja skills already give UIKit a run for its money! :smiley: )

My point is that it’s an unsustainable architecture at the moment. I’m attempting to get the conversation moving forward to what would us (as @Blockstack) need to do to support fully native apps while being Apple guidelines compliant.

2 Likes

Yeah. This is super vital for sure.

2 Likes

So what is the current proposal/solution for this guys? cc: @larry @itsProf

My proposed (and maybe the only) solution is to open a direct line with Apple and expose our case to them.

I’m not sure I fully understand this - Could someone please explain why the web server needs to accessed from another app?

Is it not possible to create the blockstack app that hosts the web server when it’s running. It shows the user all of the apps within the same iOS app? The blockstack iOS app would be responsible for doing sandboxing for each of the apps executing within its scope, but it’s possible to securely do that and keep it open source for audits. The blockstack iOS app would act as an app store as well as the place where all apps run.