How can I setup twilio call record? - ios

I have an iOS app with Twilio calls and voice record.
I'm using Twilio Client iOS SDK.
When user want to call the connection is created with code:
TCDevice* _device ...;
TCConnection* _connection ...;
NSDictionary* parameters = nil;
parameters = [NSDictionary dictionaryWithObjectsAndKeys:
phoneNumber,#"userId",
#"false",#"record",
nil];
_connection = [_device connect:parameters delegate:self];
When user want to record voice message I use this parameters:
parameters = [NSDictionary dictionaryWithObjectsAndKeys:
phoneNumber,#"userId",
#"true",#"record",
nil];
Calls are always successful, but the record is often interrupted when the user speaks very softly or silence the first few seconds. In this case, the server returns a null Url of the record.
How can I cancel an interrupt call record if the silence?
Is it possible to remove the voice warning before the recording: "Please, leave a message after the beep"?
In which place it should be set: in an application, on home server or in the dev tools on Twilio?

Check out the Twilio docs on using recordings: https://www.twilio.com/docs/api/twiml/record
The default timeout is 5 seconds, which means if there is silence for 5 seconds (or perhaps someone speaking very softly) then the recording ends. Perhaps increasing the timeout will resolve this for you?

Related

Multiple contexts , create only if not exists

I have a view controller that is performing an afnetworking request , and upon the response , I am adding that response to my main MOC , and saving it.
My app is a realtime app , and so , performing certain kinds of requests will send messages from server to client via a long lived web socket. What happens is ,when a client sends a single message , he will receive the same message via socket (and I am going to add apns functionality later on, so he will receive the same functionality via apns as well)
I want the web socket to use a background context, so my UI is taxed less.
Right now I am performing a fetch to see if data already exists. If it does not, then I am adding to the context. This check is being done on the socket side as well as the api side.
My concern is , since they are both going to be checked at such close time intervals to each other, is it possible for them to both say that data doesn't exist, and then both will add to the db, causing an unwanted duplicate?
This is my code for clarification:
if ([Chat fetchById:[jsonBody valueForKey:#"id"] withContext:self.managedObjectContext]==nil) {
NSLog(#"GOT NIL FROM SOCKET");
Chat *chat = [Chat initWithContext:self.managedObjectContext];
chat.id = [jsonBody valueForKey:#"id"];
chat.body = [jsonBody valueForKey:#"body"];
chat.user = [User fetchByID:[jsonBody valueForKey:#"user_id"] inContext:self.managedObjectContext];
NSString *date = [jsonBody valueForKey:#"created_at"];
chat.created_at = [TimeFormatter NSDateFromServerString:date];
chat.group = [Group fetchByID:[jsonBody valueForKey:#"grp_id"] inContext:self.managedObjectContext];
[self.managedObjectContext save:nil];
}

How can I receive update status(data) when I request ride with UBSDKRideRequestViewController (Uber SDK)

I have added Uber SDK in my application. I didn't request project to Request full access. It's on development. and I have issues that I can't find an answer (I'm using sandbox mode.)
Q. I need to test. If I requested and driver is already accepted. How can I know the time that he will arrive or other status e.g.arrived . and How can I send notification to my user in my application when driver is arrived. I see UBSDKRideRequestViewControllerDelegate response only error case.
this's my code.
UBSDKRideParametersBuilder *builder = [[UBSDKRideParametersBuilder alloc] init];
[builder setPickupToCurrentLocation];
[builder setDropoffLocation:dropoffLocation];
UBSDKRideParameters *parameters = [builder build];
NSArray<UBSDKRidesScope *> *scopes = #[UBSDKRidesScope.RideWidgets,UBSDKRidesScope.Profile,UBSDKRidesScope.Request];
UBSDKLoginManager *loginManager = [[UBSDKLoginManager alloc] init];
UBSDKRideRequestViewController *vc = [[UBSDKRideRequestViewController alloc] initWithRideParameters:parameters loginManager:loginManager];
vc.title = #"Uber";
vc.delegate = self;
please advice thanks.
Currently, the Ride Request Widget does not provide you notifications for changes in trip status. You can, however, get the status of the current trip by using a RidesClient and calling fetchCurrentRide which will give you details about the current trip. In order to access trips from the widget on this endpoint, however, you will need the all_trips scope. This will require you to handle login separately from the RideRequestViewController. You can use the LoginButton or LoginManager to request the AllTrips and RideWidgets RidesScopes
In terms of testing, you can update the status of a sandbox trip by making a PUT request to the /v1/sandbox/requests/{request_id} endpoint with a JSON body in the form {"status": "accepted"} (replacing the status you want to see). This status change would then be reflected in your app. You can find more information on the sandbox on the Uber Developer Site

Apigee user authentication, access_token, and cache login session in iOS

I'm new to Apigee and can't seem to wrap my head around it. I am familiar with implementing an iOS app that talks to a database via a webservice call. The call would involve passing back and forth JSON or variables though POST, GET, etc.
The user flow I envision is a lot like Facebook long term token storage. Here are the steps:
Type username and password to login.
The app will remember the access_token in the keychain.
The access_token will be used with any future requests such as updating profile. This way the user doesn't have re-login every time he/she is using the app.
Log out will clear all the token.
If the token is invalid or expired, the app will take the user back to login.
I've taken multiple routes and ended up getting stuck on all of them when it comes to Apigee.
ROUTE 1
I made a call to logInUser and receive access_token in return.
[self.apigeeDataClient logInUser:username password:password];
All this is good until I want to update user's email address using the code below.
NSMutableDictionary *requestDict = [NSMutableDictionary dictionary];
[requestDict setObject:email forKey:kDataEmail];
NSString *url = [NSString stringWithFormat:#"%#/%#/%#/users/%#?access_token=%#", BASE_URL, UG_ORG_NAME, APP_NAME, [userData objectForKey:kDataUUID], self.accessToken];
NSString *op = #"PUT";
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithDictionary:requestDict]
options:0
error:&error];
[self.apigeeDataClient apiRequest:url operation:op data:[NSString stringWithUTF8String:[jsonData bytes]]];
It seems that every other time it's giving me "No content to map to Object due to end of input" error. I checked out this thread but have no luck. I made sure the JSON object is not null. I tried changing the operation from PUT to POST and GET. None of which update the email address in the database.
ROUTE 2
Instead of using apiRequest, I switched to updateEntity.
NSMutableDictionary *requestDict = [NSMutableDictionary dictionary];
[requestDict setObject:email forKey:kDataEmail];
[requestDict setObject:kDataUsers forKey:kDataType];
[requestDict setObject:self.accessToken forKey:kDataAccessToken];
NSString *entityID = [userData objectForKey:kDataUUID];
[self.apigeeDataClient updateEntity:entityID entity:requestDict];
It looks promising except I started getting "Subject does not have permission" like the issue described in this thread. I tried calling assignPermissions like mentioned in Apigee document but that didn't solve the problem. I even provide access_token with the call, even though I shouldn't have to.
In the attempt to avoid calling login also tried calling storeOAuth2TokensInKeychain and retrieveStoredOAuth2TokensFromKeychain mentioned here. That didn't work either.
The only thing way to resolve this error is by calling logInUser before making a call to updateEntity. This means the user will have to login every time he/she wants to use the app. I know I can store username/password in the keychain. But before I do that I'm wondering if there's better solution out there.
I know it's a long post. So thank you for reading this far. Any pointers are greatly appreciated.

Twilio TCDevice connect timeout

I am wondering if there is a way to change the timeout on the outgoing call from [TCDevice -connect:delegate] in the Twilio iOS client. I have tried playing with different key/value pairs in the connect options NSDictionary but nothing seems to have an effect.
Megan from Twilio here.
For using timeout from the mobile client, you can embed the timeout parameter in the connect:delegate: method of TCDevice:
https://www.twilio.com/docs/api/client/ios/TCDevice#connectDelegate
For example:
NSDictionary *params = #{#"timeout": #"10"};
self.connection = [self.device connect:params delegate:self];
It sounds like you were trying this, but maybe missed to get this timeout argument in your TwiML app and add it into the response which is eventually sent to HUrl.

Paypal IOS SDK issues (can't communicate with servers)

I am trying to process a paypal payment using the latest IOS SDK 2 - BASICALLY i'm trying to follow the example at -
https://github.com/paypal/PayPal-iOS-SDK/blob/master/docs/single_payment.md
without much luck.
Background
I'm in Australia.
I'm using the paypal sdk to take a payment in IOS app. the app then makes a call to a PHP web server that will validate the paypal payment and then update a subscription on the PHP server backend.
What I've done and where I'm getting stuck.
I've setup a classic API application.
I've set the production and sandbox environments using -
[PayPalMobile initializeWithClientIdsForEnvironments:
#{PayPalEnvironmentProduction : #"HIDDEN",
PayPalEnvironmentSandbox : #"HIDDEN"}
];
With the text HIDDEN replaced with the real ones.
I used the following code, that successfully starts the paypal dialog -
[PayPalMobile preconnectWithEnvironment:PayPalEnvironmentSandbox];
PayPalPayment *payment = [[PayPalPayment alloc] init];
NSDecimalNumber *total_cost = NSDecimalNumber decimalNumberWithString:#"4.30"];
// Amount, currency, and description
payment.amount = total_cost;
payment.currencyCode = #"USD";
payment.shortDescription = #"test";
// Use the intent property to indicate that this is a "sale" payment,
// meaning combined Authorization + Capture. To perform Authorization only,
// and defer Capture to your server, use PayPalPaymentIntentAuthorize.
payment.intent = PayPalPaymentIntentSale;
// Check whether payment is processable.
if (!payment.processable) {
[self display_message: #"Payment could not be processed. This can happen for a variety of reasons, i.e. the payment amount was negative, etc. Please contact us if you believe you have received this message in error."];
return;
}
// Create a PayPalPaymentViewController.
PayPalPaymentViewController *paymentViewController;
paymentViewController = [[PayPalPaymentViewController alloc] initWithPayment:payment
configuration:self.payPalConfiguration
delegate:self];
// Present the PayPalPaymentViewController.
[self presentViewController:paymentViewController animated:YES completion:nil];
The paypal dialog appears but then displays a "can't communicate with servers error, try again later".
the following appears on the xcode console -
2014-03-25 10:42:22.432 PayPal SDK: Request has failed with error:
pp_service_error_json_parse_error - System error. Please try again later. (500) | PayPal Debug-ID: a26da2c300c31 | Details: (
{
"ns_error" = "Error Domain=NSCocoaErrorDomain Code=3840 \"The operation couldn\U2019t be completed. (Cocoa error 3840.)\" (No value.) UserInfo=0xbadecd0 {NSDebugDescription=No value.}";
}
).
so QUESTION (1) any ideas why this is happening.
and QUESTION (2) after this works and I can make a payment, do I then need to confirm the payment info returned from paypal? i.e. do I -
Extract the payment id from the SDK callback.
Create a rest app id in paypal in addition to the classic one, and
then get an auth token via a rest call to payal. without the rest
app, i don't seem to have the secret key, etc to access the paypal
rest service.
Then use the auth token and id from (1) to make another rest call
to get the payal payment info and validate it (i.e. check the amount
is whats expected etc)?
Hope that makes sense.
PS I find the docs incredibly confusing.
EDIT: Ok, so next day without anything changed, i tried running the app again, this time different xcode console error - "invalid client credentials". nowhere in this example at https://github.com/paypal/PayPal-iOS-SDK/blob/master/docs/single_payment.md does it specify client credentials except for this part around client ids -
[PayPalMobile initializeWithClientIdsForEnvironments:
#{PayPalEnvironmentProduction : #"HIDDEN",
PayPalEnvironmentSandbox : #"HIDDEN"}
];
which i've set correctly. are their additional credentials that need to be set before launching paypal ios sdk ui?

Resources