ACINQ / phoenix

Phoenix is a self-custodial Bitcoin wallet using Lightning to send/receive payments.
https://phoenix.acinq.co
Apache License 2.0
644 stars 97 forks source link

Improved handling of iOS notifications permissions #345

Closed robbiehanson closed 1 year ago

robbiehanson commented 1 year ago

In the past, we used "silent" push notifications. These were unreliably delivered to the application. In the event they were actually delivered, they allowed Phoenix to receive a payment as long as:

However, we recently switched to the more reliable method of using notification service extensions (#280). Interestingly this doesn't rely on "background app refresh" permissions. Instead it relies on the Notification Settings:

 

 

In order for Phoenix to receive payments in the background, iOS must launch and run our notification service extension (UNNotificationServiceExtension) when it receives a push notification.

The only reliable configuration is when:

What's more, if we don't properly request permission for notifications within the app, then permissions are implicitly disabled.

Traditionally, asking for permission means a screen like this is displayed to the user:

You're only allowed to ask the user once. Further requests are ignored by iOS - nothing is displayed to the user, and your permissions don't change. Because of this Apple has recommended that you ask the user for permission when it's related to an action they're taking within the app.

That is the traditional way to get notification permissions. But there is another way that I think works better for us: provisional permission.

If instead you ask for provisional permission to display notifications, iOS will immediately grant your request, and you will be given the following permissions:

(You'll notice that we're granted permission to run our notification service extension.)

And the first time you display a notification, the user will see something like this:

So to summarize the situation on iOS:

What to do ... ?

I think the most important thing is actually receiving the payment in the background. If the user receives the payment, but the app icon doesn't have a badge... well that's better than NOT receiving the payment. If they receive the payment, but the notification wasn't on the lock screen, but only in the notification center... well that's also better than NOT receiving the payment.

Apple's decisions have made things difficult for us, and a bit confusing for the users. Take another look at the screenshots from the Notification settings above. It looks like you're just controlling where the little push notification window is allowed to be displayed. Except you're actually not - you're turning on & off background payments. Because you're controlling whether or not Phoenix is allowed to run in the background.

So probably the most elegant solution for now is to request provisional permissions. This means we won't have to prompt the user for permission when they first start using the app. And by default our extension has permission to run.

If the user disables "background payments" then we'll warn them:

&npsp; 

We'll add a new "Background payments" configuration:

  

Tapping on "Customize in iOS settings" takes the user directly to the proper screen. Also the user can remove the amount from the notification:

And if they fully disable background payments, we explain the problem and how to fix it:

robbiehanson commented 1 year ago

The root of the problem we're trying to solve is this:

^ This is the screen within iOS Settings that allows the user to control notifications.

If I turn off notifications for Signal, I still receive the messages within Signal. I'm only turning off the little push notification windows. I quickly learn that the iOS notification settings simply control what gets displayed in iOS. (E.g. banners, badges, etc).

And it's the same for Facebook. If I disable notifications for Facebook, I still see the posts in my feed. I'm only disabling notifications on iOS.

It's the same for WhatsApp, or Twitter, or Yahoo Finance, or any other app that I can think of.

The problem is that it's not the same with Phoenix. If the user disables notifications, they do not receive the payments within Phoenix. And this is not what they expect.

(I believe this problem is solved with async payments. But those are still a work in progress. What we have right now is the best we can do at the moment.)

So we have to explain to the user:

The settings > display options > background payments Screen lists several options that can be checked by the user ; are those options in addition to the iOS settings for Phoenix?

I'm trying to use this screen to explain the above. Tapping any of those checkboxes takes you to the iOS settings. (Note that it's not possible to programmatically change those settings within Phoenix. The user must make these changes within iOS.) So the effect is something like this:

Video Demo

I think my goal with this design was simply to link the two things mentally: notification settings <=> background payments

They're related. They're in the same screen. I have to enable the "notification center" to enable background payments. And if I'm worried about privacy: there's an option right there to hide amounts.

I don't know if I accomplished my goal. The screenshots can be confusing. But interacting with the UI is more intuitive, and easier to grok.

Maybe I should clearly explain on that screen that "show in notification center" is required.

dpad85 commented 1 year ago

Ok I understand now. I was not able to test on a device so I was just looking at the screenshots and they made me think that you need to fiddle with those settings within Phoenix. But it's just an information screen.

And by the way, we don't have to detail why background payments are enabled. My suggestion is:

Maybe I should clearly explain on that screen that "show in notification center" is required.

It's already done in the "disabled" scenario so I think you're good.

robbiehanson commented 1 year ago

Updated UI: