Update Twilio capability token in background - ios

I'm developing a VoIP application for iOS using Twilio iOS SDK.
The application should always be online, it should always be able to receive an incoming call. I. e. it should be able to live in background for several days or several weeks.
But the maximum expiration period of Twilio capability token is 24 hours. So, the application has to periodically update the capability token.
Is there a reliable way to update the token in background?
The only solution I found is to update the token in TCDeviceDelegate's method device:didStopListeningForIncomingConnections:.
But this solution is unreliable: if updating of the token fails, there is no means to retry the update.

Twilio developer evangelist here.
Would it be an option for you to instead of updating the capability token manually, you listened to a callback from TCDevice? One of it's callbacks is called TCDeviceIncomingStateOffline and according to the documentation:
the TCDevice may enter the TCDeviceIncomingStateOffline states because
the capabilities have expired. In these cases, the capabilities will
need to be updated. If the device is currently listening for incoming
connection, it will restart the listening process (if permitted) using
these updated capabilities.
So if you were to listen to a change in TCDevice where it becomes offline, you could easily then refresh the token. The listening process will then only start when the capabilities are updated.
Hope this helps you

Related

Apple Push Notifications from a serverless MongoDB App Services backend

I have been setting up Apple Push Notifications for an iOS app, using JSON Web Tokens rather than certificates.
I can generate a JWT and make the required POST request from within the app (using the Swift-JWT package) and the notification is delivered.
I am using MongoDB Realm, which has serverless functions (in JavaScript with a Node environment) that are called from the iOS app. A scheduled trigger updates my JWT, as Apple advise it should be refreshed every hour.
However, despite trying several Node modules for making the POST request there were always errors (like “BadDeviceToken” or “InvalidProviderToken”).
I finally got it working using the node-apn package! However, I have two queries about using it in this serverless function context:
It tries to keep a connection open to the Apple server, which would be fine, except it might mean a new connection is opened every time the function is called. Calling Provider.shutdown() does not seem to stop the connection. I don’t think I can have a long-running process to receive future requests in a serverless context.
Apple advise not refreshing the JWT more often than every 20 minutes. node-apn manages the JWT for you, but in a serverless context, will it be generating a new token every time the function is called? Notifications do seem to get delivered every time I test it in development mode (to the Apple sandbox endpoint).
I’d be grateful for clarity on these points, and whether node-apn is appropriate to use in serverless functions.
Update
Provider.shutdown() not working seems to be a recognised issue.
I was able to shut down using this workaround:
Provider.client.endpointManager._endpoints.forEach(endpoint => endpoint.destroy());
I would still like to know about whether it is reasonable for this to be used in a serverless function. I am concerned about JWT being refreshed with every request, which Apple may not like!
I have scanned through Apple's documentation on this and given some thought to your question about refreshing tokens within a serverless context.
You could imagine the following approach for ensuring that you refresh the token no more than once every 20 minutes and at least once every hour, as per Apple's documentation:
Generate the token for sending a single notification request
Send the notification, and then after, in the background, save that token to some collection (e.g apn_tokens) inside of MongoDB (optionally alongside a createdAt timestamp field)
On the next request to send a push notifcation, fetch the stored JWT token from your server.
If the token's createdAt date (or iat field on the JWT itself) is less than an hour (or within some threshold less than the hour e.g 50 mins), then reuse the token in sending the push notification request
Otherwise, restart the process from step 1!
Note on this process: It would require that your database (or theapn_tokens collection) is only accessible from trusted sources (i.e your cloud application/functions alone), if they aren't already. Clients should not have access to this table in any way. You can imagine setting Collection-Level Access Control for your serverless environment. As an extra layer of security, you could imagine deleting "expired" tokens after re-generation in step 1, such that there is only one token present in the table at any time in order to prevent potentially active tokens from laying around in the database without use.
I hope this helps!

Is it possible to record incoming or outgoing call in iPhone?

I am trying to record incoming and outgoing calls in iPhone... Is it possible to record calls in iOS ?
Please let me know. Thanks in advance.
Yes you can.
With the use of AudioToolbox and libkern/OSAtomic.h
First of all you need to trigger when an incoming call coming.
Fire an event when ever there is Incoming and Outgoing call in iphone?
Recording the call this is what you exactly looking for.
SO post
Note:
Apple allows these hooks only when your application in foreground.
Conditions that allow your app runs in background:
For tasks that require more execution time to implement, you must request specific permissions to run them in the background without their being suspended.
In iOS, only specific app types are allowed to run in the background:
Apps that record audio content while in the background
Apps that keep users informed of their location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP)
Apps that need to download and process new content regularly
Apps that receive regular updates from external accessories
Reference link
You can go through this link below:
Record the conversation of phone - ios
There is no public API for recording the calls made (or received) by the built-in Phone app.
You will have to implement your own phone calling mechanism. You'll probably want to use VoIP. (That is what Google Voice uses, for example.) You'll need to run your own server on the Internet, or contract with an existing VoIP service. You'll want to use in-app purchase to let the user buy minutes, because it costs money to run your own server or use a third-party service.

iOS Remote Notifications Badge Count Strategy When Network Connection Is Poor

I am trying to understand the best practice for remote notifications on iOS when the user has a particularly poor network connection or no network connection.
The scenario is such:
The user gets some remote notifications and at some point in the future opens the app. At this point I wan't to let the server know ASAP that the badge count is now zero. I am using server side badge count management as the only way you can update the icon badge reliably is in the APNS payload. However the call to the server fails as there is no network connectivity. Then the user puts the app into the background so I can't make any further calls to the server if network came back. Subsequently a new remote notification comes in but the badge number is wrong because the server doesn't know it needed to be zeroed.
Am I missing something here? Any advice gratefully received as I haven't found any articles online dealing with this scenario.
Yes, you have implemented in right way. We can't do anything if there is problem in internet connection. Badge count is managed by server only. So, whenever you open application, application will update Zero to server. Now, if it is not properly updated to server then it is not possible to manage it from Mobile side.

Keep iOS App alive to work with MQTT protocol

For a project I need many clients to subscribe to different hardware devices. In this setup the clients are iOS - Devices. The hardware is something like a raspberry pi but i don't think this matters. This hardware devices send a signal if it measures some kind of information. This is a rare event and possibly could never happen.
Purpose of the app is to warn the user when some kind of event appears in a location he is interested to.
I planed to implement this using the MQTT protocol.
That is where my problem is. To work with MQTT the app needs to send PINGREQ every few minutes even when the app is in background. Also the app needs to receive its subscriptions and handle them immediately.
This is what I planned to do:
Set the "UIBackgroundModes" key in Info.plist to "voip".
Mark the socket as voip socket to wake the app when it receives something
Set the keepAliveTimer:callback: and send the PINGREQ
.. as described here
My questions are: Will Apple allow this? My app is not an VoIP app. If no, are there any alternatives to this approach?
If Apple policies doesn't allow your to put your MQTT client App running in the background, then the solution should be to implement an additional push service.
A push service subscribes to your MQTT broker and sends push notifications to your mobile devices, so that either they have the MQTT client App running or not they will get the events.
Yes!
There is a chance that apple can reject your application when you are using VOIP(even though your app is not a VOIP Kind of application) to keep application alive!
I'm using Location services which is a proper solution to keep application alive in background mode.
Ask permissions to use location services even when the app in background mode & after getting the allow call back,set your location manager's desired accuracy to worst,distance filter to 99999(means your app will be notified if the user travels more than 99999 Meters from last location update call back)
By altering the desired Accuracy and distance filters you can save the user's battery consumption,otherwise your app will consumes lot of energy
That was one proper way which makes your application to run in background for more than 2 days continuously (Already using in our projects).
HTH! Have fun in coding :)

Can I constantly send network request by updating location when application is entering background?

I have a application need send user's location information to server.
With setting "Required background modes",It can call didUpdateToLocation.
But I can send network request in didUpdateToLocation and not reject by Apple?
Thanks for answer.
It all depends. If the user completely understands that their data will be sent to your servers (and saved?) it will not be rejected by Apple. But it can't consume tons of battery, it also can't run for more than 24 hours with the user reactivating it. They put that in place so you can't have people use your app to stalk some one.

Resources