I have implemented this piece of code for basic auth and sometimes doesn't work on first time:
func doRequestWithBasicAuth(completion : (success : Bool, html: String?, error : NSError?) -> Void) {
if let user = self.user {
let loginString = NSString(format: "%#:%#", user.login!, user.pwd!)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = loginData.base64EncodedStringWithOptions(nil)
let url = NSURL(string: user.service!.getURL())
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
if error == nil {
let htmlString = NSString(data: data, encoding: NSUTF8StringEncoding)
completion(success: true, html: htmlString as? String, error: nil)
} else {
completion(success: false, html: nil, error: error)
}
}
} else {
completion(success: false, html: nil, error: NSError())
}
}
This method is attached to a button, so on first tap I get this error:
BASIC AUTH ERROR: Error Domain=NSURLErrorDomain Code=-1012 "The
operation couldn’t be completed. (NSURLErrorDomain error -1012.)"
UserInfo=0x7bad5770
{NSErrorFailingURLKey=https:///auth/Logon.do,
NSErrorFailingURLStringKey=https:///auth/Logon.do,
NSUnderlyingError=0x7b9c47f0 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error -1012.)"}
On second tap, call works fine... I can't understand why.. I print user login, psw and url: are the same on twice calls..
Any idea?
Related
I am trying to transition into a new segue after I confirm that I get a the session ID from the Udacity API. However, I cannot get any code to run after this. The session ID and all the information will print, but nothing will complete after. Is there something I am doing wrong in the function? I tried performing the UIUpdates then just tried printing "Hello" but that has not worked either. Below is some code and also my GitHub profile.
https://github.com/SteveBurgos95/UdacityMapProject
#IBAction func loginButton(_ sender: Any) {
UdacityClient.sharedInstance().loginWithUsername(emailTextField.text!, password: passwordTextField.text!){ (success, error) in
performUIUpdatesOnMain {
if success {
print("Hello")
} else {
print("Hey")
}
}
}
private func completeLogin() {
emailTextField.text = ""
let controller = storyboard!.instantiateViewController(withIdentifier: "TableMapViewController") as! UINavigationController
present(controller, animated: true, completion: nil)
It seems to me like you're never calling your completionhandler in UdacityClient.swift when the dataTask finishes (both in case of error and success)?
This should be something like this:
let task = session.dataTask(with: request as URLRequest) { data, response, error in
// Make sure there is no error, or else
guard error == nil else { // Handle error…
completionHandler(false, error?.localizedDescription)
/*
func sendError(_ error: String) {
print(error)
let userInfo = [NSLocalizedDescriptionKey : error]
completionHandlerForGET(nil, NSError(domain: "taskForGETMethod", code: 1, userInfo: userInfo))
*/
return
}
completionHandler(true, nil)
}
After looking through the code the UI is not getting updated because your have not implemented the sucess block in UdacityClient.swift. The sucess block/closure escapes. So you won't receive a callback in
UdacityClient.sharedInstance().loginWithUsername(emailTextField.text!, password: passwordTextField.text!){
Change the function like below
func loginWithUsername(_ username: String, password: String, completionHandler: #escaping (_ success: Bool, _ errorMessage: String?) -> Void ) {
let request = NSMutableURLRequest(url: URL(string: "https://www.udacity.com/api/session")!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = "{\"udacity\": {\"username\": \"\(username)\", \"password\": \"\(password)\"}}".data(using: String.Encoding.utf8)
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) { data, response, error in
if error != nil
// Handle error…
/*
func sendError(_ error: String) {
print(error)
let userInfo = [NSLocalizedDescriptionKey : error]
completionHandlerForGET(nil, NSError(domain: "taskForGETMethod", code: 1, userInfo: userInfo))
*/
return
}
completionHandler(true,nil)
let range = Range(5..<data!.count)
let newData = data?.subdata(in: range) /* subset response data! */
print(NSString(data: newData!, encoding: String.Encoding.utf8.rawValue)!)
}
task.resume()
}
I'm trying to send an http request in swift.
I got a method (sendHttpRequest) that take as argument a dictionary<String,AnyObject> and trying to send a request to localhost with a little server in php. When I tap button that call this function an error occur
"Optional(Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSErrorFailingURLStringKey=46.101.145.122/salvobertoncini.com/servo.php, NSErrorFailingURLKey=46.101.145.122/salvobertoncini.com/servo.php, NSLocalizedDescription=unsupported URL, NSUnderlyingError=0x1763cef0 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}})"
Here is the code:
func sendHttpRequests(data : Dictionary<String, AnyObject>)
{
let session = NSURLSession.sharedSession()
do
{
let request = try NSJSONSerialization.dataWithJSONObject(data, options: .PrettyPrinted)
let url = NSURL ( string : "127.0.0.1/Server/servo.php")
let finalRequest = NSMutableURLRequest(URL: url!)
finalRequest.HTTPMethod = "POST"
finalRequest.HTTPBody = request
let task = session.dataTaskWithRequest(finalRequest){ data,response,error in
if error != nil
{
print("Error -> \(error)")
}
do
{
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject]
print("Result -> \(result)")
}
catch
{
print("Error -> \(error)")
}
}
task.resume()
}
catch
{
print(error)
}
}
I'm working on a passbook capable swift application and i'm in front of a strange problem.
Randomly, the passbook i download from my server is corrupted (the same downloaded can be good or corrupted).
Here is the code :
func openPass(pass: PKPass)
{
let passname = "Benight Ticket"
var passcontroller = PKAddPassesViewController(pass: pass)
passcontroller.delegate = self
self.presentViewController(passcontroller, animated: true, completion: nil)
}
func getTicketPassbook()
{
let TicketID: String = "2gBOZqWwNj"
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let request = NSMutableURLRequest(URL: NSURL(string: "https://exemple.com/index.php")!)
request.HTTPMethod = "POST"
let postString: String = "ObjectId=" + TicketID + "&authKey=\"exemple\""
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
println("response = \(response)")
if (error == nil) {
// Success
let statusCode = (response as! NSHTTPURLResponse).statusCode
if (statusCode == 200)
{
println("Success: \(statusCode)")
var pkfile : NSData = NSData(data: data)
var pass: PKPass = PKPass(data: pkfile, error: nil)
self.openPass(pass)
}
// This is your file-variable:
// data
}
else {
// Failure
println("Faulure: %#", error.localizedDescription);
}
})
task.resume()
}
The error is the following : 2015-08-22 16:18:28.328 Application[10302:1018965] BOM could not extract archive: Couldn't read PKZip signature
And other times it works.... It's really at random times that it works or fail...
EDIT : Sometis i've also the following error : 2015-08-23 01:19:19.483 Benight[3467:994898] Invalid data error reading pass pass.com.apple.demo/8j23fm3. The passTypeIdentifier or teamIdentifier provided may not match your certificate, or the certificate trust chain could not be verified.
fatal error: unexpectedly found nil while unwrapping an Optional value
I am new to iOS developing and need some help with JSON and what to be returning. I have the following function in my modal:
func loginRequest(username: String, password: String, completionHandler: ((NSURLResponse!, JSON, NSError?) -> Void)) {
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: ""correct post url"\(username)/\(password)")
request.HTTPMethod = "POST"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let httpResponse = response as? NSHTTPURLResponse
var json = JSON(data: data!)
println(json)
})
}
This does successfully return the JSON if I print it inside this function. However, the following code in my view controller yields no errors but fails to return the JSON at all.
#IBAction func signIn(sender: UIButton) {
modal.loginRequest("Test", password: "Pass") { (response, json, error) -> Void in
println(json)
println("Hello")
if (json != nil) {
Do parsing stuff
}
}
In my ViewController, json does not return nil, it doesn't return at all. The code prints in from my modal but does not show in the VC. How am I calling the function wrong?
Your function doesn't call the completion handler closure which is passed as param. If you want access the data however, you have to call the completionHandler closure. This is how your code should be:
func loginRequest(username: String, password: String, completionHandler: ((NSURLResponse!, JSON, NSError?) -> Void)) {
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: ""correct post url"\(username)/\(password)")
request.HTTPMethod = "POST"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let httpResponse = response as? NSHTTPURLResponse
var json = JSON(data: data!)
println(json)
// call the closure argument here, to pass the asynchrounsly retrieved vallues
// back to the caller of loginRequest
completionHandler(response, json, error)
})
}
I have a backend hosted on heroku using django and I have an iOS app consuming that api. Sometimes the app throws this error
locman err: Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"
The backend for that same request throws this error
sock=client at=error code=H18 desc="Request Interrupted" status=503
How should I handle this in iOS? It seems like its a problem with the app. Am I just sending up too many requests at once?
heres what my api controller looks like
class func getPictures(location_id: String, completionHandler:( cardImageArray: [CardImage] )->() ){
var bodyString: String = "location_id=\(location_id)"
bodyString = bodyString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let url: NSURL = NSURL(string: BASE_URL + "/api/v1/get_pictures" + "?" + bodyString)!
let req: NSMutableURLRequest = NSMutableURLRequest(URL: url)
req.HTTPMethod = "GET"
//req.HTTPBody = bodyString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
NSURLConnection.sendAsynchronousRequest(
req,
queue: NSOperationQueue.mainQueue())
{ (res: NSURLResponse!, data: NSData! , err: NSError!) -> Void in
let jsonDict = JSON(data: data, options: NSJSONReadingOptions.AllowFragments, error: nil)
if (jsonDict["response"].int == 1){
var cardImageArray: [CardImage] = []
if let photo_urls = jsonDict["photo_urls"].array{
// NSString(data: data, encoding: nil)
for photo_url_raw in photo_urls{
if let url_string = photo_url_raw.string{
let ci = CardImage(urlstring: url_string)
cardImageArray.append(ci)
}
}
return completionHandler(cardImageArray: cardImageArray)
}
}else{
println("error in get pictures")
if let errorMessage = jsonDict["error"].string{
return
}
}
}
}
Figured out this was the error message being printed when location manager can't decide what the users location is. Just handled the error and had the user click a button to try again.