1

I've integrated Twilio Programmable Chat, but I've had some issues with push notifications that I'm trying to sort out.

I'm looking at my code vs the example provided at https://www.twilio.com/docs/chat/ios/push-notifications-ios

The first thing I notice is that in the User Notification Setttings section(beyond the extra t in the name of the section), the deprecated method [self.chatClient registerWithToken:nil]; from V1.0 is used. In the current documentation for V 2.2.2, we have - (void)registerWithNotificationToken:(nonnull NSData *)token completion:(nullable TCHCompletion)completion, which specifies nonnull NSData* for the token parameter. So, we can't pass nil any longer. Is there anything we're now supposed to do for the if(notificationSettings.types == UIUserNotificationTypeNone) case within - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings of our app delegate? (example provided in tutorial section mentioned above) Right now I just skip that step, and ensure that my updatedPushToken property is set to nil.

I'm also wondering what the - (void)handleNotification:(nonnull NSDictionary *)notification completion:(nullable TCHCompletion)completion method on the TwilioChatClient actually does. I see that the delegate has 5 different methods for notifications. Does this handleNotification method simply call the appropriate delegate method? I didn't use this method myself, I just show an alert view with the message of the notification right now, so I'm wondering if there are additional benefits under the hood that I'm missing out on, or even potential bugs I'm introducing by not using the TwilioChatClient handler.

The last and most important thing I'm wondering, that isn't touched in the tutorial, is how to handle registering for push notifications when a user has signed out and signed back in later. Is the deviceToken returned from - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken meant to be stored somewhere with more permanence than a property of a singleton? Can I re-obtain it elsewhere, either via Twilio or maybe an iOS method I'm unaware of? It seems once I sign a user out, I'm unable to receive Notifications again when they sign in to a different or even the same user. I see that there is a deregisterWithNotificationToken:completion: method, but since it requires a nonnull token, I can only call it based on the tutorial if my app hasn't been closed. What's the recommended way to hang on to this token? NSUserDefaults? Somewhere on my server's database?

Edit: I have another question, actually. If I uncheck the read status box, then re-check it, on a chat instance configuration, will that reset everyone's unread channel count? I had the setting of the consumption horizon / read status done improperly, and I also have a lot of channels hidden from users even though they are in them... so, with the badge count enabled, users are probably seeing very high numbers any time they get a single message, and won't be able to completely reduce this number back down to 0, even if they open every channel they can currently view. I'd prefer to just reset this number. As mentioned in my comments, I dislike that the only options I have are no notification badge, or a notification badge explicitly set to the number of channels that have unread messages... I would most prefer an option to just increment the badge, and, barring that, the notification that does not include a specific number. I want people to see that they have chats, as it is very important, but I don't want these high numbers being displayed, and those unread messages don't stay relevant permanently. Only new unread messages are relevant.

Jake T.
  • 4,308
  • 2
  • 20
  • 48
  • After doing some testing I see that calling `registerWithNotificationToken:completion:` using nil will show a warning when done explicitly, simply returns a result in the block that returns false for `isSuccessful` and contains the error message `No notification token provided.` So, nothing will crash, but it appears to be a completely unnecessary call in the tutorial. The proper, up to date method is called within the function called when a token exists. If you use that example code with the up to date SDK, though, you'll get a compiler error since the method does not exist. – Jake T. Apr 30 '18 at 18:44
  • After some more digging, it appears that simply calling `[UIApplication sharedApplication] registerForRemoteNotifications]` after push notifications have been approved will immediately call `- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken` again. Apple specifically recommends not caching this token, and instead calling that method to obtain it again as needed. Unless that's wrong, only the middle question is left. Is there a benefit to implementing `handleNotification` if I don't intend to use the delegate methods? – Jake T. Apr 30 '18 at 19:27
  • I know Twilio Devs frequent the tag here. So just gonna drop a thought. I currently have different targets for my iOS app - prod and dev. So they have different bundle identifiers and require different APNS certs. It looks like at some point they've added a keys feature to the Apple dev console, which can give you a much easier to use key that can be linked to multiple apps APNS certs. It would be cool to offer this as a means to add push configuration for iOS! It's a bit less tedious and straight forward on the user end. – Jake T. May 01 '18 at 15:48
  • My notification count is always a constant number, when I send a single message. I see that it's supposed to be the number of channels I have unread messages in. But I went through and read all my messages. The value never changes. And I see there's only the option to set the badge count. I would love the option just to set the notification badge without a count, or just incrementing the badge, rather than explicitly setting the count. – Jake T. May 01 '18 at 17:15
  • I also have a ton of bad APNS Bindings from old test accounts. I don't know how large of an issue this is on prod. But I notice I'm getting a handful of debug alerts with each push because I changed the APNS credentials to my test target of my iOS app. I had three bindings for the old cert, which are now failing with every send of a push notification. So it tries to send 4, and only the most recent is going through. Is there a webhook to delete the old bindings as they get errors, so the same dead endpoints don't continuously trigger error logs? – Jake T. May 01 '18 at 17:18
  • This problem was likely introduced from my lack of using a persistent method to get the `updatedPushToken`, I may not have had it set on my chat manager singleton when I went to deregister the client, so now instead I fetch it again with `registerForRemoteNotifications` before trying to de-register – Jake T. May 01 '18 at 17:19
  • One thing I would really love with this chat stuff is some more information about the output from the logs of TwilioChatClient... I've found next to 0 information on how to read that stuff, or even figure out what is triggering it. I get tons of logs ranging from WARNING, CRITICAL, to FATAL, but things seem to work on the surface... – Jake T. May 01 '18 at 17:25
  • Ahh the notification badge was due to not properly setting the consumed index... Got that sorted. Still, I think an increment option rather than explicitly setting to the number of unread messages makes more sense. If I already got the notification and looked and don't care about a message, when I get a new notification I have 1 relevantly new notification, not however many I've had in the past and chose to ignore. – Jake T. May 01 '18 at 17:36

1 Answers1

2

I'm on the Programmable Chat iOS SDK team and hope to help with some of your questions above.

The references to registerWithToken: as well as the instruction to call it with a nil parameter when no token is present/known are both deprecated as you've noted. We'll get the documentation and tutorial updated to reflect this - thank you!

Today, handleNotification:completion: is optional. Its purpose is to parse the userInfo portion of the push payload and provide the callbacks you mentioned to help your user know the events occurred. It's not detrimental to skip this step today but in the future it's likely these callbacks will be used to provide more feedback around delivery of notifications inside of Programmable Chat so you may want to look back into implementing this at a future date.

When your users log out, it is recommended you call the deregisterWithNotificationToken:completion: method to ensure their privacy. If you do not de-register the token from being associated with their identity, they will continue to receive notifications for that identity even if they later use an access token on that device with a different identity in the future. Mechanisms for managing notification bindings programmaticaly via our REST API are on our roadmap, but I do not have a release date to share at this time.

As mentioned in Apple's push notifications documentation, it is good to not cache the device token or assume push device tokens will never change since this token may change with future registrations. Likewise, it is recommended you pass along the token given by Apple to Programmable Chat whenever you receive a device token from Apple to ensure we have the most up to date token to reach your users device with.

Badge count as passed along by APNS reports the number of channels with unread messages for the given user. There are a couple of reasons that come to mind why you may be seeing an outdated result here. In your client, are you calling the setLastConsumedMessageIndex:completion: on TCHMessages (or one of the related methods in the same class) to update the unread status on the backend? After this is done, you should see an updated push come in with an updated badge count after a short period of time. Another possibility is if you do have outdated bindings for other identities still on the channel you are testing with that were not logged out/de-registered. Please note that while the application is in the foreground, you are responsible for updating the badge count yourself - iOS will not do it. This is one spot where you may wish to ensure you are calling handleNotification:completion: since we will call that if we receive a badge update. You can also look at the payload and make the call to update the badge count as needed directly in the receiving delegate on the UIApplication. One way to test this would be to set up a new channel and test messages with that, updating the consumption horizon when appropriate. You can find more info in the consumption horizon documentation. Below, you can find an example of updating the badge count in repsonse to Programmable Chat's delegate method:

- (void)chatClient:(TwilioChatClient *)client notificationUpdatedBadgeCount:(NSUInteger)badgeCount {
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeCount];
}

Leveraging Apple's provider authentication tokens instead of certificates is something our notifications team is investigating but we don't have a date to share on when support for that will ship at this time.

Please let me know if I can help any further or if I missed any of your questions!

Thank you, Randy

rbeiter
  • 156
  • 2
  • Thanks a lot for the extensive reply, @rbeiter. It looks like the only thing that didn't get brushed on was anything about decoding the logs that I get. Even when things appear to be working fine for me, I'll see tons of WARNING and CRITICAL logs from twilio, and I have no clue which, if any, require action on my part to fix, or if they're just some under the hood warnings that are handled by the SDK. I do love Twilio for your documentation - above and beyond most APIs out there. But I do feel there would be benefit from a more comprehensive iOS example / tutorial that utilizes everything. – Jake T. May 01 '18 at 21:13
  • I've taken a look through the examples provided on GitHub, and they don't touch on push notifications, and I think one includes adding delegate methods for the AccessManager but never sets up an AccessManager. The examples are great, and more than most APIs offer, just definitely a little room for improvement that could make implementing such a nuanced aspect of mobile apps a ton easier. – Jake T. May 01 '18 at 21:16
  • Do you know if there are plans to add more administrative functionality to the dashboard for Chat? I've been toying with the idea of updating our admin dashboard to include chat admin tools, but it's a big time sink if they're going to be added to the Twilio dashboard. Things like adding/removing members, deleting messages, etc. I have noticed functionality has increased over time, and imagine there are more features to come, but I'm torn between spending dev time myself that'll be more or less wasted vs. not having access to important features for too long due to assuming they were coming. – Jake T. May 01 '18 at 21:19
  • You're welcome @jake-t, we do have some log entries reported which are incorrectly attributed to CRITICAL severity which should not be. Working to get those addressed in the near future. This page - https://www.twilio.com/docs/chat/error-handling-and-diagnostics - contains what we have so far in the way of troubleshooting and logging. It's in the process of being expanded so definitely expect to see it level up before long. – rbeiter May 01 '18 at 21:25
  • The kitchen sink demo, https://github.com/twilio/twilio-chat-demo-ios, should demonstrate pushes pretty thoroughly. Definitely let us know if something can be clearer there. In the ChatManager.m class you'll find how to handle registration/handling of pushes including queuing them up if the client isn't yet initialized. The ChannelsList VC shows handling pushes as they come in. – rbeiter May 01 '18 at 21:25
  • I'll reach out to the team to see what will be coming in the form of expanding the dashboard in the ways you mention and let you know what I find out! – rbeiter May 01 '18 at 21:27
  • Ah, I was using the demo at https://github.com/TwilioDevEd/twiliochat-objc, I think I found the link from some Twilio documentation page. It's the one I referred to that does not include push notifications or properly sets up the access manager. I'll take a look at the one you posted. It also seems the "Evaluating Logs" section is what I was looking for on the other link you posted, though it's fairly sparse. I hope to see it 'leveled up'! – Jake T. May 01 '18 at 21:59