The Synch SMS verification I get is only 4 digits. How do I make it 6 digits?
Below is the code I am using. This code just seems to send 4 digits for verification whereas I would like it to be 6 digits.
var verification: Verification! // this is defined in the class
private func initiateVerification() {
verification = SMSVerification(applicationKey: SinchConstants.applicationKey, phoneNumber: phoneNumber)
verification.initiate { (success, error) in
dispatch_async(dispatch_get_main_queue(), {
if success {
self.handleSuccess()
} else {
if let error = error where error.code == -1001 {
self.handleSuccess()
} else {
self.handleError(error)
}
}
})
}
}
you cant control it in the dashboard, but I am happy to change it for you if you mail in your appkey and that you want to 6 digits to support#sinch.com
Related
I have created an AB Test on Firebase(not Published yet) and added token of a test device.
But the value is not coming for the provided key.
As AB testing is in Beta, so is it a bug on Firebase side that it doesn't work on test devices?
let remoteConfig = RemoteConfig.remoteConfig()
remoteConfig.fetch(withExpirationDuration: 0) { status, _ in
if status == RemoteConfigFetchStatus.success {
remoteConfig.activateFetched()
let ab_test_value = remoteConfig.configValue(forKey: "ab_test_key").stringValue
print(ab_test_value)
}}
The ab_test_value is coming as empty.
Try this may your variable is deallocated when response come
var remoteConfig:FIRRemoteConfig?
///
var expirationDuration = 43200;
// If in developer mode cacheExpiration is set to 0 so each fetch will retrieve values from
// the server.
if (remoteConfig?.configSettings.isDeveloperModeEnabled)!
{
expirationDuration = 0;
}
self.remoteConfig?.fetch(withExpirationDuration: TimeInterval(expirationDuration))
{
(status, error) -> Void in
if status == .success
{
print("Config fetched!")
self.remoteConfig?.activateFetched()
}
else
{
print("Config not fetched")
print("Error \(error!.localizedDescription)")
// return
}
self.displayWelcome()
}
}
I'm trying to get the users first name using cloud kit however the following code is not getting the users first name and is leaving firstNameFromFunction variable empty. Does anyone know how to achieve this in iOS 10?
let container = CKContainer.default()
container.fetchUserRecordID { (recordId, error) in
if error != nil {
print("Handle error)")
}else{
self.container.discoverUserInfo(
withUserRecordID: recordId!, completionHandler: { (userInfo, error) in
if error != nil {
print("Handle error")
}else{
if let userInfo = userInfo {
print("givenName = \(userInfo.displayContact?.givenName)")
print("familyName = \(userInfo.displayContact?.familyName)")
firstNameFromFunction = userInfo.displayContact?.givenName
}else{
print("no user info")
}
}
})
}
}
the permission screen that comes up when asking for the first time, IMO, is very poorly worded. They need to change that. It says "Allow people using 'your app' to look you up by email? People who know your email address will be able to see that you use this app." This make NO sense. This has nothing to do with asking the user to get their iCloud first name, last name, email address.
Speaking of email address - this and the phone number from the lookupInfo property is missing - i.e. set to nil, even though those values are legit and correct. Filing a bug tonight.
First, you will need to request permission to access the user's information.
Then, you can use a CKDiscoverUserIdentitiesOperation. This is just like any other CKOperation (eg. the modify record operation). You just need to create a new operation with the useridentitylookupinfo. Then you will also need to create a completion block to handle the results.
Here is an example function I created:
func getUserName(withRecordID recordID: CKRecordID,
completion: #escaping (String) -> ()) {
if #available(iOS 10.0, *) {
let userInfo = CKUserIdentityLookupInfo(userRecordID: recordID)
let discoverOperation = CKDiscoverUserIdentitiesOperation(userIdentityLookupInfos: [userInfo])
discoverOperation.userIdentityDiscoveredBlock = { (userIdentity, userIdentityLookupInfo) in
let userName = "\((userIdentity.nameComponents?.givenName ?? "")) \((userIdentity.nameComponents?.familyName ?? ""))"
completion(userName)
}
discoverOperation.completionBlock = {
completion("")
}
CKContainer.default().add(discoverOperation)
} else {
// iOS 10 and below version of the code above,
// no longer works. So, we just return an empty string.
completion("")
}
}
First you need to ask the user for permission to be discovered.
Use CKContainer.default().requestApplicationPermission method passing .userDiscoverability on applicationPermission parameter.
The CKContainer.default().discoverUserInfo method is deprecated on iOS 10. Instead use CKContainer.default().discoverUserIdentity method.
Do something like:
CKContainer.default().requestApplicationPermission(.userDiscoverability) { (status, error) in
CKContainer.default().fetchUserRecordID { (record, error) in
CKContainer.default().discoverUserIdentity(withUserRecordID: record!, completionHandler: { (userIdentity, error) in
print("\(userIdentity?.nameComponents?.givenName)")
print("\(userIdentity?.nameComponents?.familyName)")
})
}
}
I have this code:
// Get phone number and make a call on tap
if heyObj[HEYS_PHONE] != nil {
if "\(heyObj[HEYS_PHONE])" != "" {
let aURL = URL(string: "telprompt://\(heyObj[HEYS_PHONE]!)")!
if UIApplication.shared.canOpenURL(aURL as URL) {
UIApplication.shared.openURL(aURL)
} else { simpleAlert(mess: "Sorry, Your device cannot make phone calls!") }
} else { simpleAlert(mess: "This user has not provided a phone number") }
} else { simpleAlert(mess: "This user has not provided a phone number") }
}
What this does:
It gets the phone number from a user and make a call on tap.
The popup looks like this:
Is it possible to change this from calling to sending a message?
Is there any function available which can do this?
I am using Quickblox example writing in Swift for chat app. It uses QMServices.
Questions:
1) is there any approach for user login in iOS application with some session_token generated in any cloud backend ?
2) please help - how to renew user sessions in right way, I always get 422 error (validation error) multiple times (
In app using QuickBlox for iOS I try to login user in appdelegate:
if Storage.sharedInstance.currentUser != nil {
if !ServicesManager.instance().isAuthorized() {
let user =Storage.sharedInstance.currentUser
ServicesManager.instance().loginOrSignUp(user) {
[unowned self] success, error in
if (success) {
self.openMainScreen()
}
}
} else {
openMainScreen()
}
}
And loginOrSignUp function is:
func loginOrSignUp(user: QBUUser!, completion: ((success:Bool, errorMessage: String!) -> Void)!) {
self.logInWithUser(user) { (success:Bool, errorMessage: String!) -> Void in
if (success) {
Storage.sharedInstance.currentUser = self.currentUser()
completion(success: success, errorMessage: errorMessage)
} else {
self.authService.signUpAndLoginWithUser(user, completion: { (response: QBResponse!, user: QBUUser!) -> Void in
if user != nil {
Storage.sharedInstance.currentUser = self.currentUser()
completion(success: true, errorMessage: errorMessage)
} else {
completion(success: false, errorMessage: response.error?.error?.localizedDescription)
}
})
}
}
}
For example using Parse cloud code I can call function from cloud code:
Parse.Cloud.define("signUp", function(req, res) {
var phoneNumber = req.params.phoneNumber;
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo('username', phoneNumber);
query.find({
success: function(results) {
if (results.length > 0) {
Parse.User.logIn(phoneNumber, secretWord).then(function (user) {
res.success(user.getSessionToken());
}, function (err) {
res.error(err);
});
} else {
var user = new Parse.User();
user.set("username",phoneNumber);
user.set("password",secretWord);
user.setACL({"*": { "read": true }});
user.signUp(null, {
success: function(user) {
res.success(user.getSessionToken());
// Hooray! Let them use the app now.
},
error: function(user, error) {
alert("Error: " + error.code + " " + error.message);
}
});
}
},
error: function(error) {
res.error(err);
}
});
});
So using Parse I can just login to app with session_token generated with cloud code.
First question: can I do the same with QuickBlox - use for login some session_token generated in any cloud backend?
And the second question: when user logged in, session is expired in 2 hours and we have to renew session ?
When user has bad connection, before he receive useful information he has to renew session every 2 hours. Even Ukrainian API for Ukrainian usage (not for for best service in the world) use token generated with login function for any other requests. User should not renew session always - he get only useful information.
But if there is no approach in Quickblox without session renewing, then how to do this renew in right way ? I am very new to iOS development, but when I used Parse, I didi not get this problems (
Im using SMS verification to verify users. My problem is that when I enter a code to verify I get invalid code. I can't for the life of me figure out why.
Calling cloud code function:
#IBAction func verifyCodeButtonTapped(sender: AnyObject) {
var verificationCode: String = verificationCodeTextField.text!
let textFieldText = verificationCodeTextField.text ?? ""
if verificationCode.utf16.count < 4 || verificationCode.utf16.count > 4 {
displayAlert("Error", message: "You must entert the 4 digit verification code sent yo your phone")
} else {
let params = ["verificationCode" : textFieldText]
PFCloud.callFunctionInBackground("verifyPhoneNumber", withParameters: params, block: { (object: AnyObject?, error) -> Void in
if error == nil {
self.performSegueWithIdentifier("showVerifyCodeView", sender: self)
} else {
self.displayAlert("Sorry", message: "We couldnt verify you. Please check that you enterd the correct 4 digit code sent to your phone")
}
})
}
}
Cloud code to verify code:
Parse.Cloud.define("verifyPhoneNumber", function(request, response) {
var user = Parse.User.current();
var verificationCode = user.get("phoneVerificationCode");
if (verificationCode == request.params.phoneVerificationCode) {
user.set("phoneNumber", request.params.phoneNumber);
user.save();
response.success("Success");
} else {
response.error("Invalid verification code.");
}
});
Your parameter names are mismatched between the iOS and JS code.
verificationCode vs phoneVerificationCode
Change
let params = ["verificationCode" : textFieldText]
To use the same parameter name:
let params = ["phoneVerificationCode" : textFieldText]
EDIT
Other issues I see with the code:
The first two lines of the iOS code create a variable and a constant from the textField's text value. Get rid of the verificationCode variable and just use the textFieldText constant.
I would add some more error states to the Cloud Code before you check if the codes are equivalent. First check if the parameter exists and the expected type and length:
var requestCode = request.params.phoneVerificationCode;
if ((typeof requestCode !== "string") || (requestCode.length !== 4)) {
// The verification code did not come through from the client
}
Then perform the same checks on the value from the user object:
else if ((typeof verificationCode !== "string) || (verificationCode.length !== 4)) {
// There is not a verification code on the Parse User
}
Then you can continue to checking if requestCode and verificationCode are equivalent.