How to append something like ?id=1 to a NSMutableURLRequest - swift

I want to display the data from this URL:
http://www.football-data.org/soccerseasons/351/fixtures?timeFrame=n14
My baseURL is let baseUrl = NSURL(string: "http://www.football-data.org")!,
so my request is let request = NSMutableURLRequest(URL: baseUrl.URLByAppendingPathComponent("soccerseasons/" + "\(league.id)" + "/fixtures?timeFrame=n14"))
But the ?timeFrame=n14 doesn't work.
Anyone knows how to solve this so I can display that data?

The problem is that the question mark in ?timeFrame=n14 is treated as part of the URL's
path and therefore HTML-escaped as %3F. This should work:
let baseUrl = NSURL(string: "http://www.football-data.org")!
let url = NSURL(string: "soccerseasons/" + "\(league.id)" + "/fixtures?timeFrame=n14", relativeToURL:baseUrl)!
let request = NSMutableURLRequest(URL: url)
Alternatively, use NSURLComponents, which lets you build an URL successively from individual components (error checking omitted for brevity):
let urlComponents = NSURLComponents(string: "http://www.football-data.org")!
urlComponents.path = "/soccerseasons/" + "\(league.id)" + "/fixtures"
urlComponents.query = "timeFrame=n14"
let url = urlComponents.URL!
let request = NSMutableURLRequest(URL: url)
Update for Swift 3:
var urlComponents = URLComponents(string: "http://www.football-data.org")!
urlComponents.path = "/soccerseasons/" + "\(league.id)" + "/fixtures"
urlComponents.query = "timeFrame=n14"
let url = urlComponents.url!
var request = URLRequest(url: url)

Related

Using facebook graph API to make HTTPS POST request in swift

When I use the url below normally on Google Chrome, I am able to create a new facebook test user, I get back a valid json with username and password, and other details back.
https://graph.facebook.com/v3.1/2232192233718728/accounts/test-users?installed=true&name=Thomasfsdks&locale=en_US&permissions=read_stream&method=post&access_token=2232192233718728|24q_TtCeh44Z0dUVm7x5pg2U5iQ
However, when I try to do it on swift, it does not seem to work correctly. I am unsure how to make it work.Below is the code in swift.
let appID = "2232192233718728"
let urlString = "https://graph.facebook.com/v3.1/" + appID + "/accounts/test-users?"
let url = URL(string: urlString)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let name = "Thomasdasfafada"
let accessToken = "2232192233718728|24q_TtCeh44Z0dUVm7x5pg2U5iQ"
let postString = "installed=true&name=" + name + "&locale=en_US&permissions=read_stream&method=post&access_token=" + accessToken
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
let responseString = String(data: data!, encoding: .utf8)
print("here"+"responseString = \(responseString)")
}
task.resume()

Set Cookies to HTTP POST Requests from Swift NSURLSession

I'm trying to use the below code but it doesn't work! Any Idea
let jar = NSHTTPCookieStorage.sharedHTTPCookieStorage()
let cookieHeaderField = ["Cookie": self.CookieValue] // var CookieValue = String()
let url = URL
let parameters = ""
let postData:NSData = parameters.dataUsingEncoding(NSASCIIStringEncoding)!
let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(cookieHeaderField, forURL: NSURL(string: url)!)
jar.setCookies(cookies, forURL: NSURL(string: url), mainDocumentURL: NSURL(string: url))
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = "POST"
request.HTTPBody = postData
let session = NSURLSession.sharedSession()
try this for setting cookies and for better usage understanding.
Below is the swift part for setting up cookie.
let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(response.allHeaderFields as NSDictionary as! [String : String], forURL: response.URL!)
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookies(cookies, forURL: response.URL!, mainDocumentURL: nil)

Swift - How to set cookie in NSMutableURLRequest

I'm trying to set cookie in my HTTP request
and I thought that below code would work:
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.setValue("key=value;", forHTTPHeaderField: "Cookie")
but this code is not working.
does anyone have idea how to set it?
Updated answer for Swift 3
You want to look at HTTPCookieStorage.
// First
let jar = HTTPCookieStorage.shared
let cookieHeaderField = ["Set-Cookie": "key=value"] // Or ["Set-Cookie": "key=value, key2=value2"] for multiple cookies
let cookies = HTTPCookie.cookies(withResponseHeaderFields: cookieHeaderField, for: url)
jar.setCookies(cookies, for: url, mainDocumentURL: url)
// Then
var request = URLRequest(url: url)
Original answer for swift 2
You want to look at NSHTTPCookieStorage.
// First
let jar = NSHTTPCookieStorage.sharedHTTPCookieStorage()
let cookieHeaderField = ["Set-Cookie": "key=value"] // Or ["Set-Cookie": "key=value, key2=value2"] for multiple cookies
let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(cookieHeaderField, forURL: url)
jar.setCookies(cookies, forURL: url, mainDocumentURL: url)
// Then
let request = NSMutableURLRequest(URL: url)
Swift 5
if let cookie = HTTPCookie(properties: [
.domain: ".my.domain.name.com",
.path: "/",
.name: "myCookieNameKey",
.value: "K324klj23KLJKH223423CookieValueDSFLJ234",
.secure: "FALSE",
.discard: "TRUE"
]) {
HTTPCookieStorage.shared.setCookie(cookie)
print("Cookie inserted: \(cookie)")
}
This may be useful for some one(Swift 5).
Avoid using NSMutableURLRequest in Swift. Instead follow the below snippet:
func request(with url: URL) -> URLRequest {
var request = URLRequest(url: url)
guard let cookies = HTTPCookieStorage.shared.cookies(for: url) else {
return request
}
request.allHTTPHeaderFields = HTTPCookie.requestHeaderFields(with: cookies)
return request
}
Here is how it works in Swift 3.x after you set cookie using HTTPCookieStorage
let cookies=HTTPCookieStorage.shared.cookies(for: URL(string: cookieURL)!)
let headers=HTTPCookie.requestHeaderFields(with: cookies!)
let request = NSMutableURLRequest(url: requestURL!)
request.allHTTPHeaderFields=headers

Submit Decimal/Float in URL Request with Swift

How can a value such as "1.5" be passed in a a URL POST request using swift?
For example:
let number = "1.5"
let numberValue = number.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let server:String = "www.someserver.com"
let phpFile:String = "/php/SomePHPScript.php"
let baseURL = NSURL(string: "http://\(server)\(phpFile)")
let url = NSURL(string: "?value=\(numberValue)", relativeToURL: baseURL)
let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
var request = NSMutableURLRequest(URL: url!, cachePolicy: cachePolicy, timeoutInterval: 10.0)
request.HTTPMethod = "POST"
var dataString = ""
let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = requestBodyData
// etc...
This compiles fine but crashes on execution. It seems converting this to JSON would fix it, but is there cleaner way?
EDIT
stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) returns optional. It needed to be unwrapped.
stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) returns optional. It needed to be unwrapped.

Why is RestKit strips my URL, swift?

I am initing my Object Manager:
let baseURL = NSURL(string:"http://xxxxx.net/api")
self.client = AFHTTPClient(baseURL: self.baseURL)
self.objectManager = RKObjectManager(HTTPClient: self.client)
But when I run my code:
objectManager.getObjectsAtPath("/json.product.gf.php", parameters: queryParameters,
success: {(requestOperation, mappingResult) -> Void in
var defaults = NSUserDefaults.standardUserDefaults()
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let d = NSDate()
defaults.setValue(dateFormatter.stringFromDate(d), forKey: "lastProductUpdate")
},
failure: {(requestOperation, mappingResult) -> Void in
NSLog("Failed Products")
})
It errors out because it is stripping "api" from my base url.
Why?
Internally RKObjectManager probably uses init?(string URLString: String, relativeToURL baseURL: NSURL?) to create the new URL from the baseURL and the relative url.
You basically have two problems in your code.
your baseURL does not end in /. The aforementioned API ignores everything behind the last / of the baseURL.
your supposed relative url starts with an /. Which means it's actually an absolute URL. This will ignore everything after the host of the baseURL
The position of the slashes is pretty important if you deal with baseURLs. It's an easy fix:
let baseURL = NSURL(string:"http://xxxxx.net/api/")
and
objectManager.getObjectsAtPath("json.product.gf.php", parameters: queryParameters,
If you have a playground nearby and want to see it yourself:
let baseURL = NSURL(string:"http://xxxxx.net/api")! // http://xxxxx.net/api
let url1 = NSURL(string: "json.php", relativeToURL: baseURL)! // http://xxxxx.net/json.php
let url2 = NSURL(string: "/json.php", relativeToURL: baseURL)! // http://xxxxx.net/json.php
let baseURL2 = NSURL(string:"http://xxxxx.net/api/")! // http://xxxxx.net/api/
let url3 = NSURL(string: "json.php", relativeToURL: baseURL2)! // http://xxxxx.net/api/json.php
let url4 = NSURL(string: "/json.php", relativeToURL: baseURL2)! // http://xxxxx.net/json.php