I am implementing iOS app where I have to implement Respoke SDK for audio and video calling. Audio and video functionality is working fine in development mode but In production mode it gives me error "Api authentication error". I have used this code for production:
[self.client connectWithTokenID:[[aryResult valueForKey:#"data"]valueForKey:#"token"] initialPresence:nil errorHandler:^(NSString *errorMessage)
{
[self showError:errorMessage];
}];
For reference, I have used this : Respoke Documentation
Please tell me what is missing in my end. Please help me out.
Thanks a lot in advance!
It seems most likely you are having one of these problems:
The value returned by [[aryResult
valueForKey:#"data"]valueForKey:#"token"] is not exactly the same
as the value returned by the Respoke server when asking for a
brokered authentication token from
https://api.respoke.io/v1/tokens due to URL encoding of the data
between the server and your iOS application or something similar.
The brokered authentication token is only valid for 20 seconds, so
perhaps too much time has passed before your iOS application
attempts to use it.
You have not switched your application out of
development mode on the Respoke developer portal, or have not
created a role to use when authenticating. This documentation
page
explains how to properly set up your application and define a role
for using brokered authentication. You can also use the example code
on that page to make sure that you are getting a valid token for
your application. This would help make sure you have your account
configured correctly.
I have resolved the issue by adding some lines of code. Now for the production mode, code will be this:
if (!sharedRespokeClient)
{
// Create a Respoke client instance to be used for the duration of the application
sharedRespokeClient = [[Respoke sharedInstance] createClient];
}
sharedRespokeClient.delegate = self;
[sharedRespokeClient connectWithTokenID:tokenStringFromServer initialPresence:nil errorHandler:^(NSString *errorMessage) {
[self showError:errorMessage];
}];
Related
EDIT: DEAR PEOPLE FROM THE FUTURE, trey-jones has fixed this issue by implementing setLoginBehavior, FBSDKLoginNative seems to have issues on FB's end not with the module.
Environment:
MacOS X 10.10.5
Ti SDK 5.1.1.GA - 5.1.2.GA
iOS 9.2
Ti.Facebook 5.0.0 - 5.0.1
My project settings (tiapp.xml) are fine (it works on every other case on both iOS and Android).
Code I'm using to invoke the login:
var fb = require('facebook');
fb.initialize();
fb.authorize();
If the Facebook app is installed to the device the fb.authorize() doesn't open up. I did not see any iOS system level messages when this happened either.
Has anyone else had luck using fb.authorize with the new sdk on iOS devices WITH the app installed. With no fb app on the system it correctly opens the browser based view.
EDIT: I have managed a workaround for this (it is not pretty) based on the fact that login works with AppC's KitchenSink.
The workaround is to add a Ti.FB loginButton to the code, doesn't matter if its not visible, initializing this will fix whatever is causing custom login's .authorize() to not work.
//Workaround button:
if(OS_IOS){
var fbHaxBtn = fb.createLoginButton({
readPermissions: ['email'],
visible: false
});
}
//It needs to be added to the window/doesn't need to be visible though
$.login_window.add(fbHaxBtn);
//Then in our custom button's code, we can fire as normal:
function doLoginClick{
fb.initialize(); //I was having unexpected issues dropping this line on Android, although the docs say its deprecated.
fb.authorize();
}
Will keep this ticket updated if/when this thing gets a formal fix.
This is my second answer on this question. I believe that my original answer offers some value to the conversation and that is why I am leaving it, but it still did not consistently solve the problem of the facebook authorization not working.
The consistent solution turned out to be modifying the official Ti.Facebook module. I will submit a pull request for this change (1 line), but for now, you can get the working module here:
Source
Pre-built
This consistently allows users to authorize by explicitly setting the login behavior to use the browser, rather than the native facebook app through fast app-switching. This is actually the intent of Facebook's developers.
I was unable to determine what is causing it to fizzle when trying to use the native app to login - it should try the next option, which is the browser - but this works, and doesn't require a TiFacebookButton either.
I hope it helps someone else!
EDIT: This answer does not solve the original question. I have left it here in case it helps with related difficulties using the Ti.Facebook module. See my other answer, to actually solve the problem. END EDIT
I commented above, but after doing so encountered some more strange behavior, with the result being that I could not reliably use the workaround given (fbHaxButton). I want to explain what was happening in my case, and show my own workaround (which is also not pretty). It's possible that the root cause is the same for both of us.
I have not bothered with Android yet, so this answer is specific to iOS.
When I started this process, I came to the conclusion that authorize was correctly opening the facebook website in safari to allow authorization, but was not firing the login event upon returning. To handle this I had already implemented the following:
facebook = require('facebook');
Ti.App.addEventListener('resumed', function (e) {
var launchOptions = Ti.App.getArguments();
if(!launchOptions.url) {
return console.warn('Ignoring resume event with no url argument.');
}
// this lib = https://github.com/garycourt/uri-js
var URI = require('vendor/uri'),
uriComponents = URI.parse(launchOptions.url),
expectedScheme = 'fb',
expectedHost = 'authorize';
// I would like to be more specific about the uri, but we are limited
// in Titanium, and this will allow us to pretty certain
// that FB is sending us back to our app
if(uriComponents.scheme.search(expectedScheme) < 0 || uriComponents.host !== expectedHost) {
return console.warn('Resume event received, but scheme is incorrect. Ignoring.');
}
// synthesize login event
facebook.fireEvent('myapp:login', {
success: 1,
token: facebook.getAccessToken(),
uid: result.id
});
});
facebook.addEventListener('myapp:login', function onFacebookAuth(e) {
facebook.removeEventListener('myapp:login', onFacebookAuth);
if(!e.success) {
// do fail action
}
// do success action
});
facebook.initialize();
facebook.authorize();
So, originally I was firing and listening for an event called 'login', which the facebook module supposedly (according to the docs) will fire after authorization is complete.
In my case, this event was being fired while my app was in the background, after authorize was called, but before the user actually clicked 'OK' in facebook. My listener would respond to this event (logging, etc), but seemed to occur in a separate thread, or somehow otherwise become disconnected from my app, as it never passed its result along to the UI. I am using Q.js (kriw-kowal) and I belive this is where the disconnect is occuring.
Ceasing to listen to 'login', and simply handling my own synthesized event has fixed my issue.
I felt that this was very difficult to explain. If you have feedback about that, and how I can be more clear about what I believe is happening, or if you believe that I have reached wrong or incomplete conclusion, let me know - I'll try to update this answer to be better.
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.
I am using the Quickblox iOS SDK 2.0.12
I have been following the instructions on Quickblox Authentication and Authorization here.
I call QBRequest createSessionWithSuccessBlock:, and then call QBRequest signUp: inside it's completion block, and then I call QBRequest logInWithUserLogin: inside the next completion block.
According to the above link, I should now have a Quickblox User Session after doing all of this. This all works perfectly and all of the calls are successful and I can see that the user is now in the Quickblox Admin Panel.
After doing this, if I make Quickblox requests they work fine. The only weird thing is that [[QBSession currentSession] currentUser] NSLogs as (null).
Anyways, if I stop running the app on the simulator, and then run the app again 10 minutes later, I check for persisted custom data so I can see if the user has already signed up or not. When the user has signed up, then I take them into the app instead of them needing to signup or login again.
Now, if I try to make any requests to Quickblox, I get the following exception:
Terminating app due to uncaught exception 'BaseServiceException', reason: 'You have missed the authorization call.
Please insert following code inside your application
[QBRequest createSessionWithSuccessBlock:errorBlock:];
Before any other code, that uses our service, but after setup credentials. Thank you.'
I don't understand why it's saying I need to create a session when I already just created one when the user first signed up. I understand that the session expires every 2 hours, but I am testing this very quickly and I am always receiving this error.
If I NSLog [QBSession currentSession] I can see that there is currently a QBSession object, but if I try to NSLog any of it's properties like sessionDetails, sessionExpirationDate, or currentUser they all log as (null).
As I know, only if you use this method - (void)startSessionForUser:(QBUUser *)user withDetails:(QBASession *)session expirationDate:(NSDate *)sessionDate , you can use this property correct. But I didn't ever use it.
For recreating a session I use [QBConnection setAutoCreateSessionEnabled:YES] and for chat I keep QBUUser in my Manager, and after entering foreground I check XMPP connection [[QBChat instance] isLoggedIn]. Maybee it may help you.
I have spent hours deleting certificates and remaking them. I've followed this tutorial https://developers.arcgis.com/en/geotrigger-service/guide/ios-push-notifications/ many times and I still cannot get push notifications to work. I was using the geoloqi.com API but they were bought by esri and just released a new api. I had push working with geoloqi.
The only thing questionable about that tutorial is where it says "Paste the pem file in the box" I just copied from finder and pasted it like it said but it's weird because usually there's a browse for file button and then you upload. I don't know, thats probably not the problem but I thought I'd bring it up.
With this test code:
[[AGSGTApiClient sharedClient] postPath:#"device/notify"
parameters:#{#"text": #"Push notifications are working!", #"url": #"http://developers.esri.com"}
success:^(id res) {
NSLog(#"device/notify success: %#", res);
}
failure:^(NSError *err) {
NSLog(#"device/notify failure: %#", err.userInfo);
}];
I get:
device/notify success: {
devices = {
TKhqTzrTSQI0DGBa = queued;
};
But I never receive the push. Does anybody have a suggestion I can try next because I am lost?
The first thing you'll want to check is whether you have the proper certificates configured for your application. The best way to do this is completely outside the Geotrigger API so that it's not adding more steps to the mix. There are any number of ways you can do this, but we have also written a guide you can follow here: https://github.com/Esri/pushlet/tree/master/client
If you are familiar with Node.js, you can run the Pushlet server yourself and send test notifications to your device. If you are not familiar with Node.js, you can follow the first two steps, Set up the Certificates and Test the Connection.
Once you have verified you are not getting any SSL errors communicating with APNS, and you have verified you can use the certificates to send a push notification to your device directly, if you're still having trouble with sending a push notification through the Geotrigger API, you can contact our support at geotrigger-support#esri.com.
I've successfully set up the "DemoApp" project from the Facebook IOS SDK to use my "OKC ThunderCast" Facebook application. I have also configured another "Tester" application from scratch to successfully use the Facebook SDK and publish stories to my news feed. However, in my production application, I always get this result when calling the "dialog" method. The full description of the error message is "Error on line 52 at column 17: Opening and ending tag mismatch: div line 0 and body"
Here's a detailed walkthrough of all of my code to make sure nothing is missed.
1) A UIViewController calls the "authorize" method
NSArray *fbPerms = [NSArray arrayWithObjects:#"read_stream", #"offline_access", nil];
[[FacebookSingleton sharedInstance].facebook authorize:fbPerms delegate:self];
Note: The FacebookSingleton is a class I wrote that always returns a single instance of the "Facebook" class. I am using it successfully in other applications.
2) Safari is opened and the user is successfully authenticated and authorized
3) The application is called back and the "handleOpenUrl" method is called, which calls the "fbDidLogin" method of the UIViewController
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
Facebook *fb = [FacebookSingleton sharedInstance].facebook;
return [fb handleOpenURL:url];
}
4) The same UIViewController handles the "fbDidLogin" event, and calls the "dialog" method
- (void)fbDidLogin
{
[[FacebookSingleton sharedInstance].facebook dialog:#"feed" andDelegate:self];
}
I also have the necessary "URL Schemes" and "URL Types" entries in the .plist file. To my eyes, I am using exactly the same code in the "DemoApp", "Tester", and production applications. But while the DemoApp and Tester work, I always see this HTML error in the feed dialog in my production application. Has anyone seen a similar issue? Could it be related to the Facebook "Bundle ID" setting in the Facebook application settings? Is there some build or .plist setting that is different?
I have invested a great deal of time into troubleshooting with no success in several weeks. Thanks in advance...
The cause of the problem was setting a value to the key "User-Agent" in the NSUserDefaults dictionary. I wanted to specify my own User-Agent to uniquely identify my iOS app. But somehow setting this value caused the problem above. When I simply renamed this key to "OKCTC-User-Agent" the error was immediately resolved.
I did log an issue on the GitHub site for the Facebook-IOS-SDK. Hopefully this will help others who have encountered similar problems.