How to deal with errors with FIRMessaging (un)subscribeToTopic? - ios

Sometimes when I call [[FIRMessaging messaging] subscribeToTopic:myTopic] (or unsubscribe) I see errors logged in the console. Sometimes they have error codes, and other times it's just a message like this:
Cannot unsubscribe to topic: /topics/my_topic with token: (null)
This one appears to be because it doesn't think it has a token, though usually when I see this I've already given it a token.
There is, however, no apparent programmatic way to know when an error occurred. There's no callback passed to the subscribe methods, and their return types are void. I think I read somewhere in my Googling of these errors that the library will retry on its own, but I can't find that back now, and it's not in the documentation for FIRMessaging anywhere. The error codes are also not documented anywhere that I can find.
One error code I remember seeing specifically is 5. My implementation used to simplistically re-subscribe / unsubscribe from each topic when the user changed any of them; when I modified this to only update the topic that actually changed, that particular error went away, so maybe it was complaining because I was subscribing to a topic that I was already subscribed to, and vice versa?
How do I deal with these errors? Is it true that the library will retry on its own? And can someone link to an error code listing?

You don't have to deal with errors that result from subscribe and unsubscribe, it is retried by the SDK automatically. See docs for more.
Issues with the current error messages is a known, we will improve them in future releases.

Related

CallKit error com.apple.CallKit.error.requesttransaction error 7

I'm using Twilio voice quickstart code https://github.com/twilio/voice-quickstart-swift.
When I make a client to client call, call doesn't connect. CallKit runs in the background though, I can see the green notification bar when I send app in the background.
Following is the error:
StartCallAction transaction request failed: The operation couldn’t be completed. (com.apple.CallKit.error.requesttransaction error 7.)
As you can see Googling doesn't help as there doesn't seem to be any solution around?
Does anyone know how to fix or debug it further?
Updated:
Attaching VoIP settings, it's certainly enabled.
Problem is in your code which you write to handle and initialise variables. There is nothing wrong in the Twilio sdk either so don't look there. Anything which you are doing beyond twilio sample code is the place to look for the problem.
I've also wasted months of my time on similar issue and found out that there was issue with initialising one variable.
You are trying to request CXStartCallAction right after another CXStartCallAction was requested. You need to end the first call correctly.
In any case you must follow correct sequence of actions. Once you user wrong action in a sequence, CallKit will return one or another error.
And DO NOT request one action immediately after another is processed. There should be some time between two requests. For example, you initiated CXStartCallAction, then you checked that user is offline and trying to end the call. If that check is quick, then "end action" may result in error. You need to wait a few milliseconds before cancelling the outgoing call.
Twilio developer evangelist here.
Have you enabled capabilities for Voice over IP in the project settings?
Try to initialize CXProvider and CXCallController sooner, before requesting CXStartCallAction
I had the same problem because the Provider and the CallController have been lazy loaded.
It looks like that the CXProvider initWithConfiguration runs asynchronously which means you need to call this early otherwise you run into the risk of having a call without the completion of the initWithConfiguration function.
Thanks to #Allen for pointing me in the right direction.

Undestanding what causes StoreKit SKErrors

It is not clear to me what exactly causes the following errors:
SKError.clientInvalid
SKError.paymentInvalid
SKError.paymentNotAllowed
I am trying to write error dialogs that are informative and instructive. But since I am not sure what causes the errors, I am not sure how to be instructive.
I guess .paymentNotAllowed occurs when parental control is enabled? And .paymentInvalid occurs when an error occurs with the payment?
But I have no idea what would cause .clientInvalid.
And do I have to handle these cloud service errors for in-app purchases? If so, what would cause them?
SKError.cloudServiceRevoked
SKError.cloudServicePermissionDenied
SKError.cloudServiceNetworkConnectionFailed

Twilio SDK General error #31000

We use Twilio SDK in our iOS app. It works fine but sometimes didStopListeningForIncomingConnections callback is called with error=31000 ("General error"). After that, the device turns to a strange state: it seems to be online but it's impossible to call it. And it shows "unconnected" state on the device.
So the questions are:
1. What does this 31000 error means?
2. What should we do in such a case? How to reconnect device to Twilio?
Megan from Twilio here.
You can see what an error for Twilio Client means here: https://www.twilio.com/docs/api/client/errors
However, 31000 is a rather vague and less than ideal error message as you describe. In this case, it is likely that the Twilio capability token has probably expired while the application is in the background, and if you merely call the listen method whenever they are receiving the 31000 generic error, it might cause the client SDK to result in a error-retry loop and crash the application eventually.
At the time of your writing with TwilioClient iOS SDK v1.2.5, it is suggested to use the following sample code in your did-stop-listening callback:
- (void)device:(TCDevice*)device didStopListeningForIncomingConnections:(NSError*)error {
if ( [self checkCapabilityTokenStillValid] ) {
// if the token has not yet expired, use the `listen` method of `TCDevice` to resume the listening state
[self.device listen];
}
else {
// restart all over by requesting a new capability token and initialize/update the `TCDevice` instance again
[self login];
}
}
The TwilioClient iOS SDK takes care of dispatching the listen and updateCapabilitiyToken: methods to the current thread for execution, therefore it's safe to call them directly in the didStopListeningForIncomingConnections. The did-stop-listening delegate method is always triggered with dispatch_get_main_queue() of Grand Central Dispatch.
Hope this may help others if they run into the same generic error.
This may or may not be the issue, we have encountered 31000 errors two times in our development and both were a result of generating the JWT on our server api. To be clear the error was a 31000 on the client, but the reason for this was in the construction of the JWT, and the params we wanted twilio to send back to our application.
When passing in an object to allow_client_outgoing or allow_client_incoming the twilio sdk concats this all in their scope attribute in their JWT. It added it to the scope:client:outgoing?appSid= which looks like a query string. That means it has a size limit of 2048. So exceeding this length generates a 31000 error.
In addition adding the objects doesn't seem to always implicitly serialize the object correctly, it introduces characters that can generate errors in their corresponding mobile sdks (but not their web sdk ... weird) so we took care of this by explicitly serializing objects to JSON before they are inserted into the JWT.
I hope both of these examples help you track down the issue.

is it possible that SKPaymentTransactionStateFailed AND SKPaymentTransactionStatePurchased are 'called'?

Is there a use case where first paymentQueue:updatedTransactions: is called with SKPaymentTransactionStateFailed and at a later time with SKPaymentTransactionStatePurchased?
I thought I saw such a behavior when the user enters a wrong password (Failed) and then the correct one (Purchased), but it doesn't seem to be the case.
I've got crashes with my app which I can only explain with the flow that first it fails and then succeeds. Does anyone know if that's a possible use case?
In some cases (when the user is asked to update their CC info, agree to new terms, or something else), there's a possibility of getting SKPaymentTransactionStateFailed before getting SKPaymentTransactionStatePurchased. So, one should not treat SKPaymentTransactionStateFailed as a definitely permanent failure.

how to get audio session initialization error status since AudioSessionInitialize was deprecated?

On start app i called AudioSessionInitialize and check result value.
If it was kAudioSessionInitializationError then i informed user that application can not work properly cause audio does not work.
But since iOS 7 this function was deprecated.
It was similar question before: A fix for AudioSessionInitialize Deprecated? but... it has no any mention about how to get initialization error status.
And of course, i know how to initialize audio session without this function: Just calling [AVAudioSession sharedInstance] cause hidden call of AudioSessionInitialize. But it returns non zero value anyway. So new interface does not allow to get initialization error status.
upd: I'm not sure it's important but i receive message to stdout (which i redirected to log file) while call with error happens:
ERROR: [7971] 146: Unable to talk to server: error 0x10000003
(268435459)
explaination why i need this:
It happens very rarely (less then 0,1% of case) but it happens for any firmware. Last case registered for iOS 7.0.3 - so it's actual return value still (btw, first case registered for first firmware my app supported: iOS 2.2). It's important feature (cause i develop alarm clock) - it allows to know user about issues in the evening and not in the morning (cause in the morning this issue will cause oversleep).

Resources