resend your request with the updated header Transmission in Swift - ios

I've this code to take the X-Transmission-Session-Id but now i need to resend the request with the updated header.
function takeXTransmissionSessionId( ){
let urls = NSURL(string: "\(url)")
let task = NSURLSession.sharedSession().dataTaskWithURL(urls!) { (data, respornse, error) -> Void in
guard error == nil && data != nil else {
print("error=\(error!)")
let alertView = UIAlertController(title: "ERROR", message: "A server with the specified hostname could not be found.", preferredStyle: UIAlertControllerStyle.Alert)
let actionView = UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil)
alertView.addAction(actionView)
self.presentViewController(alertView, animated: true, completion: nil)
return
}
if let httpStatus = respornse as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
let sesionID = httpStatus.allHeaderFields["X-Transmission-Session-Id"]
if sesionID == nil {
let alertView = UIAlertController(title: "ERROR", message: "The request has not been applied because it lacks valid authentication credentials for the target resource.", preferredStyle: UIAlertControllerStyle.Alert)
let actionView = UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil)
alertView.addAction(actionView)
self.presentViewController(alertView, animated: true, completion: nil)
}else{
//print("\(respornse!)")
//print("\(sesionID!)")
self.XTransmissionSessionId = "\(sesionID!)"
}
}
}
task.resume()
}
My problem is i tray many times in a different ways but i don't know what i need to do.
Thanks!

This is the code for do what i need:
request.HTTPMethod = "POST"
request.addValue("\(XTransmissionSessionId)", forHTTPHeaderField: "X-Transmission-Session-Id")

Related

Error in background/main thread using API

I try to call my API, but I get an error:
Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.
I understand that I need to call DispatchQueue, but I don't understand where I need use it.
My code:
let currentUser = Auth.auth().currentUser
currentUser?.getIDTokenForcingRefresh(true, completion: { (idToken, error) in
if let err = error {
self.unknownError(error: err)
} else {
var request = URLRequest(url: URL(string: "https://phss.ru/api/booking/cancel")!)
request.httpMethod = "POST"
let cancelBooking: [String: Any] = ["booking_id": self.documentIDs]
let jsonData = try! JSONSerialization.data(withJSONObject: cancelBooking, options: [])
request.httpBody = jsonData
request.addValue("Bearer \(idToken!)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
if let err = error {
self.unknownError(error: err)
} else {
let alertController = UIAlertController(title: NSLocalizedString("Cancel successful", comment: "Cancel successful"), message: "", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizableOk, style: .cancel, handler: nil))
self.present(alertController, animated: true, completion: nil)
}
})
task.resume()
}
})
You need to present your UIAlertController on the main thread because the completion callback of URLSession.shared.dataTask(with:completionHandler:) runs on a background thread.
DispatchQueue.main.async {
let alertController = UIAlertController(title: NSLocalizedString("Cancel successful", comment: "Cancel successful"), message: "", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizableOk, style: .cancel, handler: nil))
self.present(alertController, animated: true, completion: nil)
}

iOS App Crashes on every device except devices connected with Xcode

My app crashes and quit when user try to register a new account but that occurs on any device except devices deployed the app with Xcode.
All the devices are registered in the developer account and running iOS 11.4.1
Here is the register button function:
#IBAction func regButton(_ sender: Any) {
usernameText = usernameTextField.text
mobileText = mobileTextField.text
emailText = emailTextField.text
passwordText = passwordTextField.text
fieldText = categoryTextField.text
print(usernameText ?? "damn")
print(mobileText ?? "damn")
print(emailText ?? "damn")
print(passwordText ?? "damn")
print(fieldText ?? "damn")
if(type=="Seeker")
{
let url1 = "http://app.alosboiya.com.sa/hourjob.asmx/insert_jobseeker?name="+usernameText!+"&phone="+mobileText!
let url2 = "&email="+emailText!+"&password="+passwordText!+"&workex="+"companyDescText!"
let url3 = "&category="+fieldText!+"&image="+"downloadURLGlobal!"
let url4 = "&unpaidhour="+"string"+"&hourpaidlast30="+"string"+"&totalhourworked="+"string"+"&balance="+"string"+"&username="+usernameText!
stringURL = url1 + url2 + url3 + url4
}else
{
let url1 = "http://app.alosboiya.com.sa/hourjob.asmx/insert_company?name="+usernameText!+"&field="+fieldText!
let url2 = "&phone="+mobileText!+"&email="+emailText!+"&password="+passwordText!+"&workex="+"companyDescText!"+"&crcopy="+"downloadURLGlobal!"+"&logo="+"string"+"&username="+usernameText!
stringURL = url1 + url2
}
if Reachability.isConnectedToNetwork()
{
if(checkbox.on==true)
{
let url = URL(string: stringURL!)
Alamofire.request(url!).responseString {
(response) in
let result = response.result.value
do {
if(result=="True")
{
let alert = UIAlertController(title: "Registration Successfully", message: "Registration Done Successfully Congratulations",
preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style:
UIAlertActionStyle.default, handler: self.doSomething))
self.present(alert, animated: true, completion: nil)
}else
{
let alert = UIAlertController(title: "Registration Failed", message: "Registration Failed Please Try Again", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
}
}else
{
let alert = UIAlertController(title: "License Agreement", message: "Check to Agree Licence Agreement", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}else
{
let alert = UIAlertController(title: "No Network Connection", message: "Connection Error Please Try Again", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
If a user will tap the button but one or both text fields are empty then your app will crash due to forced unwraping (! mark) which you use in your code.
Example: if mobileText field will be empty then the your app will crash:
let url1 = "http://app.alosboiya.com.sa/hourjob.asmx/insert_jobseeker?name="+usernameText!+"&phone="+mobileText!
the solution is to use guard statement
guard let usernameText = usernameTextField.text,
mobileText = mobileTextField.text,
emailText = emailTextField.text,
passwordText = passwordTextField.text,
fieldText = categoryTextField.text else {
return
}

Getting login data from mysql in swift login form using json

I am new to swift . I have developed a login form which verifies data from mysql database and for that I have used json and swift code . But there is an issue in my code , after providing the login details when I click on the submit button .It shows the alert view that the credentials are invalid ,even after providing the correct credentials . I have attached the code below . Please if anyone can help me
class ViewController: UIViewController {
#IBOutlet weak var PASSWORD: UITextField!
#IBOutlet weak var USERNAME: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func submitbtn(_ sender: Any) {
let username: NSString = self.USERNAME.text! as NSString
let password: NSString = self.PASSWORD.text! as NSString
if username.isEqual(to: "") || password.isEqual(to: ""){
let myAlert = UIAlertController(title: "Alert", message:"All fields are required to fill in", preferredStyle: UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler:nil)
myAlert.addAction(okAction);
self.present(myAlert, animated: true, completion: nil)
// return
}
else
{
let post:NSString = "UserName\(username)&PassWord\(password)" as NSString
NSLog("PostData : %d", post)
let url = "http://demo.talentclouds.in/API/LoginHandler.asmx/Login?username=admin#penn.in&password=123"
let postData:NSData = post.data(using: String.Encoding.ascii.rawValue)! as NSData
let postLength:NSString = String ( postData.length ) as NSString
let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"
request.httpBody = postData as Data
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoder", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
// let responseError:NSError?
// let response:URLResponse?
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
DispatchQueue.main.async {
if(error != nil)
{
//Display an alert message
let myAlert = UIAlertController(title: "Alert", message: error!.localizedDescription, preferredStyle: UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler:nil)
myAlert.addAction(okAction);
self.present(myAlert, animated: true, completion: nil)
}
//parsing the response
do {
//converting resonse to NSDictionary
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let username = parseJSON["username"] as? String
if(username != nil)
{
UserDefaults.standard.set(parseJSON["username"], forKey: "username")
UserDefaults.standard.set(parseJSON["password"], forKey: "password")
UserDefaults.standard.synchronize()
// let username : NSInteger = json?.value(forKey: username as String)as! NSInteger
// NSLog("Success : %ld ", username)
// if (username != nil)
// {
print("Login OK")
}
else{
print("Login Failed")
let alert = UIAlertController(title: "Invalid", message: "Invalid Credentials", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
catch {
print("Login Failed")
let alert = UIAlertController(title: "Error", message: "Please check your internet connection", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
})
//executing the task
task.resume()
}
}
}
Your issue there
let username = parseJSON["username"] as? String
It should be read profile dictionary first
if let profile = parseJSON["Profile"] as? [String:Any],
let username = profile["username"] as? String
Here Full code:
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
DispatchQueue.main.async {
if(error != nil)
{
//Display an alert message
let myAlert = UIAlertController(title: "Alert", message: error!.localizedDescription, preferredStyle: UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler:nil)
myAlert.addAction(okAction);
self.present(myAlert, animated: true, completion: nil)
}
//parsing the response
do {
//converting resonse to NSDictionary
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
if let profile = parseJSON["Profile"] as? [String:Any],
let username = profile["username"] as? String
{
UserDefaults.standard.set(parseJSON["username"], forKey: "username")
UserDefaults.standard.set(parseJSON["password"], forKey: "password")
UserDefaults.standard.synchronize()
// let username : NSInteger = json?.value(forKey: username as String)as! NSInteger
// NSLog("Success : %ld ", username)
// if (username != nil)
// {
print("Login OK")
}
else{
print("Login Failed")
let alert = UIAlertController(title: "Invalid", message: "Invalid Credentials", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
catch {
print("Login Failed")
let alert = UIAlertController(title: "Error", message: "Please check your internet connection", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
})
//executing the task
task.resume()
}
}
}

Optimizing a CloudKit sign-in on app launch with error handling. How can I better handle the optional chaining? Swift 3.0/Xcode 8.1

Is there a cleaner, swiftier solution to handle the optional chaining happening in my code below? I'm setting up the user for CloudKit access in my custom function runCKsetup():
func runCKsetup() {
container.requestApplicationPermission(.userDiscoverability) { (status, error) in
guard error == nil else {
if let error = error as? NSError {
if let errorDictionary: AnyObject = error.userInfo as? Dictionary<String, AnyObject> as AnyObject? {
let localizedDescription = errorDictionary["NSLocalizedDescription"]! as! String!
if localizedDescription! == "This operation has been rate limited" {
// Create an alert view
let alert = UIAlertController(title: "Network Error", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Test for Connection", style: UIAlertActionStyle.default) { (action) in
self.runCKsetup()
})
self.present(alert, animated: true, completion: nil)
} else {
// Create an alert view
let alert = UIAlertController(title: "Sign in to iCloud", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default) { (action) in
})
self.present(alert, animated: true, completion: nil)
}
}
}
return
}
if status == CKApplicationPermissionStatus.granted {
self.container.fetchUserRecordID { (recordID, error) in
guard error == nil else {
self.presentMessageAlert((error?.localizedDescription)!, title: "Error", buttonTitle: "Ok")
return }
guard let recordID = recordID else { return }
self.container.discoverUserIdentity(withUserRecordID: recordID, completionHandler: { (info, fetchError) in
//do something with the users names: e.g. print("\(info?.nameComponents?.givenName) \(info?.nameComponents?.familyName)")
})
}
}
}
}

stop animating ActivityViewIndicator after invalid login

I'm new to iOS programming and currently is playing around with some tutorial found online. I was trying to include an ActivityViewIndicator in the sign in view. When the "Sign In" button is tapped, an ActivityViewIndicator should show up and it show be hidden when sign in is invalid. My problem is where should i put the self.signInViewIndicator.stopAnimating(); when the sign in is invalid? I have enabled the Hides When Stopped option.
#IBAction func SignInButtonTapped(sender: AnyObject) {
let userUsername = userUsernameTextField.text
let userPassword = userPasswordTextField.text
if(userUsername.isEmpty || userPassword.isEmpty) { return}
signInViewIndicator.startAnimating()
// Send user data to server side
let myUrl = NSURL(string: "http://192.168.168.135:8080/userLogin.php")
let request = NSMutableURLRequest(URL:myUrl!)
request.HTTPMethod = "POST"
let postString = "username=\(userUsername)&password=\(userPassword)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("error=\(error)")
return
}
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var resultValue = parseJSON["status"] as? String
println("result: \(resultValue)")
var isUserSignedIn:Bool = false
if(resultValue=="Success") {
isUserSignedIn = true
// Login is successful
NSUserDefaults.standardUserDefaults().setBool(isUserSignedIn, forKey: "isUserLoggedIn")
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion: nil)
} else {
self.signInViewIndicator.stopAnimating()
var messageToDisplay:String = parseJSON["message"] as! String!
if(!isUserSignedIn)
{
messageToDisplay = parseJSON["message"] as! String!
}
dispatch_async(dispatch_get_main_queue(), {
// Display alert message with confirmation
var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:nil)
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
})
}
}
}
task.resume()
}
You almost got it rigth, you can never update the UI from a thread other than the main thread, as you was already displaying the alert in the main thread I just had to move your message "self.signInViewIndicator.stopAnimating()" to inside that dispatch block:
dispatch_async(dispatch_get_main_queue(), {
// Display alert message with confirmation
self.signInViewIndicator.stopAnimating()
var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:nil)
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
})

Resources