Can't make Alamofire run in the simulator - xcode

i have installed alamo fire and cannot seem to make a request with it.
#IBAction func loginButtonTapped(sender: UIButton) {
let groupLogin = groupUserNameEntry.text;
let groupPassword = groupPasswordEntry.text;
print("line of debug code before request")
Alamofire.request(.GET, "http://api.myserver.com/folks/authenticate", parameters: ["login": groupLogin!, "password": groupPassword!])
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
print("line of debug code inside request")
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
when run in the simulator i get the first line of debug code before request but the output in the "All Output" viewer is (lldb), which i understand to mean low level debugger. It seems like the request is not getting made, but there is no error output. The url works fine in a browser.

The text of a UITextField is an optional value, so what you are doing is assigning to groupLogin an optional value, but groupLogin is not an optional value type, so everything breaks.
You need to safely unwrap optional values, there're many ways to achieve this, but in my opinion guard is the best:
#IBAction func loginButtonTapped(sender: UIButton) {
guard let groupLogin = groupUserNameEntry.text else {
print("groupUserNameEntry.text is nil, stop execution")
return
}
guard let groupPassword = groupPasswordEntry.text else {
print("groupPasswordEntry.text is nil, stop execution")
return
}
print("line of debug code before request")
Alamofire.request(.GET, "http://api.myserver.com/folks/authenticate", parameters: ["login": groupLogin, "password": groupPassword])
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
print("line of debug code inside request")
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}

Related

URL Sessions returning server not found even though URL is valid - Swift4

I am trying to use URLSession to do a API Request. The request/link is the following https://api.nanopool.org/v1/zec/user/t1KcroGeTYz6Tn4hsgwnuiUzw65xgAAaknc
When I put it into safari it loads. When I try preform the request in Xcode 9 with Swift4, I get an error that the server was not found.
Here is the entire error.
The top to lines are just from a print function, the rest is the error.
Here is the code I used:
let api = "https://api.nanopool.org/v1/zec/user/"
let urlString = api+addr
print(urlString)
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!.localizedDescription)
}
guard let data = data else { return }
print(data)
}.resume()
What is the issue with it that it causing it to return that the server cannot be found even though its a valid URL/Request?

Alamofire Response Property List

I'm going through a tutorial and am attempting to make an alamofire request to a property list. In the closure for the response property list, I use the arguments (_, _, result). However, XCode gives me the error:
Cannot convert value of type '(_, _, _) -> Void' to expected argument
type 'Response -> Void'
I am using alamofire 3.0 beta.
Alamofire right now is in version 3.3 according to the releases in the repository, since the version 3.0 it has change a little.
In you use the Response Handler your closure need to look like this:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.response { request, response, data, error in
print(request)
print(response)
print(data)
print(error)
}
And if you use for example the Response JSON Handler everything is encapsulated now in the response like in this code:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
Or you can use this code for more easily handling:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
switch(response.result) {
case .Success(let value):
if let JSON = value {
print("JSON: \(JSON)")
}
case .Failure(let error):
print(error.description)
}
}
I hope this help you.
this works for me, if doesn't work for you, paste your code to inspect problem please.
var params : Dictionary<String,String> = ["key":"value"]
Alamofire.request(.POST, "someURL" ,parameters: params).responseJSON()
{
response in
let data = JSON(response.result.value!)
if(data != nil)
{
var status = data["status"] as? String
}
}

How to send some count of POST/GET requests simultaneously?

I'm learning swift, trying to send 2 and more requests not one by one, but simultaneously. Is it possible with NSURLSession?
NSURLSession is asynchronous which means it is sent on a different thread and can be run multiple at once.
This link explains and gives an example on how to handle the response back on the main thread etc:
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started
func sendRequest() {
let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
var dataTask: NSURLSessionDataTask?
let url = NSURL(string: "http://www.url.com")
dataTask = defaultSession.dataTaskWithURL(url!) {
data, response, error in
dispatch_async(dispatch_get_main_queue()) {
//Handle response
if let error = error {
//Error - handle 'error'
print(error.localizedDescription)
} else if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
//Success - handle 'data'
}
}
}
}
dataTask?.resume()
}
Hope this helps

Nesting Alamofire callbacks or return value for Global Usage

I am currently trying to nest Alamofire requests to use data that I have already successfully received using GET requests.
For this piece of code I have used Rob's answer in this question
How to return value from Alamofire
However, I can not either nest the Alamofire requests or use them by separate.
This is what I am trying to do
override func viewDidLoad() {
super.viewDidLoad()
var currentFoodType: String = ""
var currentFoodList: String = ""
//debug
//this is how I get back the token from NSUserDefault
if let myToken = userDefaults.valueForKey("token"){
// calling method to get the user info
getUserInfo(myToken as! String)
// calling method to get the product type
func getFoodCategory(completionHandler: (NSDictionary?, NSError?) -> ()) {
getProductTypes(myToken as! String, completionHandler: completionHandler)
}
getFoodCategory() { responseObject, error in
// use responseObject and error here
let foodTypesJSON = JSON(responseObject!)
//to get one single food category
currentFoodType = (foodTypesJSON["types"][0].stringValue)
print(currentFoodType)
/////////////////////////////////////////
func getFoodsByCategory(completionHandler: (NSDictionary?, NSError?) -> ()) {
print("getting " + currentFoodType)
self.getProductsByType(myToken as! String, productType: currentFoodType, completionHandler: completionHandler)
}
getFoodsByCategory() { responseObject, error in
// use responseObject and error here
print("responseObject = \(responseObject); error = \(error)")
return
}
return
}
}
Then the two other functions I am calling from there are very straight forward Alamofire requests with callbacks to the completionHandlers above
//GET THE PRODUCT TYPES FROM THE SERVER
func getProductTypes(myToken: String, completionHandler: (NSDictionary?, NSError?) -> ()) {
let requestToken = "Bearer " + myToken
let headers = ["Authorization": requestToken]
let getProductTypesEndpoint: String = BASE_URL + PRODUCT_TYPES
Alamofire.request(.GET, getProductTypesEndpoint, headers: headers)
.responseJSON{ response in
switch response.result {
case .Success(let value):
completionHandler(value as? NSDictionary, nil)
case .Failure(let error):
completionHandler(nil, error)
}
}//END ALAMOFIRE GET responseJSON
}
The above function returns a single food like "Desserts" which will be used in the following function to GET all the desserts from the server
//GET THE PRODUCTS FROM THE SERVER GIVEN A CATEGORY
func getProductsByType(myToken: String, productType: String, completionHandler: (NSDictionary?, NSError?) -> ()){
let requestToken = "Bearer " + myToken
let headers = ["Authorization": requestToken]
let getProductTypesEndpoint: String = BASE_URL + PRODUCT_BY_TYPE + productType
Alamofire.request(.GET, getProductTypesEndpoint, headers: headers)
.responseJSON { response in
switch response.result {
case .Success(let value):
print("no errors")
let auth = JSON(value)
print("The pbt GET description is: " + auth.description)
completionHandler(value as? NSDictionary, nil)
case .Failure(let error):
print("there was an error")
completionHandler(nil, error)
}
}//END ALAMOFIRE GET responseJSON
}
and this works well because when I print within the getProductsByType function
using
print("The pbt GET description is: " + auth.description)
I get the JSON with all the products but the problem is in the viewDidload function where I am nesting the callbacks
getFoodsByCategory() { responseObject, error in
// use responseObject and error here
print("responseObject = \(responseObject); error = \(error)")
return
}
the print within that bit is showing me that something is wrong so I can not parse my response as I desire.
Because I get the following
responseObject = nil; error = nil
So my guess is that there must a be a different method to nest these callbacks?
Take a look at chained promises from PromiseKit. This also works well with Alamofire:
func loadFoo() -> Promise<Bar> {
return Promise<Bar> { fulfill, reject in
Alamofire.request(.GET, "url")
.responseJSON { response in
switch response.result {
case .Success(let value):
let bar = Bar(fromJSON: value)
fulfill(bar)
case .Failure(let error):
reject(error)
}
}
}
}
// Usage
getBar()
.then { bar -> Void in
// do something with bar
}
.error { error in
// show error
}
This is very simple example, but you can find more relevant examples in documentation.

Swift URL Response is nil

I have created a custom DataManager class. Inside it I want to fetch data in a method and return an NSData object to convert to JSON afterwards.
I have tried to get the data using the completionHandler but no luck:
class func fetchData() -> NSData? {
var session = NSURLSession.sharedSession(),
result = NSData?()
let DataURL : NSURL = NSURL(string: "http://...file.json")!
let sessionTask = session.dataTaskWithURL(DataURL, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
result = data
})
sessionTask.resume()
return result
}
The dataTask runs asynchronously. That means that the completion handler closure will not be called by the time you return from fetchData. Thus, result will not have been set yet.
Because of this, you should not try to retrieve data synchronously from an asynchronous method. Instead, you should employ an asynchronous completion handler pattern yourself:
class func fetchData(completion: #escaping (Data?, Error?) -> Void) {
let session = URLSession.shared
let url = URL(string: "http://...file.json")!
let task = session.dataTask(with: url) { data, response, error in
completion(data, error)
}
task.resume()
}
And you'd call it like so:
MyClass.fetchData { data, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
// use `data` here; remember to dispatch UI and model updates to the main queue
}
// but do not try to use `data` here
...
FYI, for the original pre-Swift 3 syntax, see previous revision of this answer.

Resources