Why is RestKit strips my URL, swift? - 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

Related

let myUrl = URL(string: returns nil in swift

let adr = "http://www.dummy.com/mobil.aspx?id=\(uyeNo)&kaynak=ios\(ulke)&req=DB2021&list=\(liste)"
let encAdr = adr.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
let myUrl = URL(string: encAdr)
myUrl is always nil. I couldn't find the reason.
I see String Interpolations in your URL string:
\(uyeNo) \(ulke) \(liste)
Have you assigned values on those three? If not, maybe that's the reason why your myURL value returns fatally nil.
Anyways, if above isn't necessarily your case, you may try the following code that may suit your need:
func myCompleteURL(uyeNo: String,ulke:String,liste: String) -> URL {
let adr = "http://www.dummy.com/mobil.aspx?id=\(uyeNo)&kaynak=ios\(ulke)&req=DB2021&list=\(liste)"
let encAdr = adr.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
let myUrl = URL(string: encAdr)
return myUrl!
}
func sampleCallFunction(){
let url = myCompleteURL(uyeNo: "i",ulke: "love",liste: "cats")
print(url)
// Prints: http://www.dummy.com/mobil.aspx?id=i&kaynak=ioslove&req=DB2021&list=cats
}
try! this Updated Answer
let urlString = "http://www.dummy.com/mobil.aspx?id=\(uyeNo)&kaynak=ios\(ulke)&req=DB2021&list=\(liste)"
let urlStringEncoding = urlString.addingPercentEncoding(withAllowedCharacters: .alphanumerics) ?? ""
guard let url = URL(string: urlStringEncoding) else {
return
}
print(url)

Master Detail app in Swift - how to convert string into URL

I'm new here, so please bear with me. I have a Master-Detail app, and in the DetailViewController.swift file, here's the configureView func where it calls a web view to open a web page.
It's complaining on the let request = URLRequest(url:url) line because url variable is defined as a string. I've tried everything but it won't work.
By the way, MasterViewController.MyVariables.urlString is an array of strings.
func configureView() {
// Update the user interface for the detail item.
if let detail: AnyObject = detailItem {
if let myWebview = webView {
let url = MasterViewController.MyVariables.urlString
let request = URLRequest(url: url)
myWebview.scalesPageToFit = true
myWebview.loadRequest(request)
}
}
}
You can either pass an URL object or create an URL object from the string that you´re passing. Anyhow you need to convert your string into an URL.
if let url = URL(string: MasterViewController.MyVariables.urlString) {
// use url in here
}
Update:
Use this for your example:
if let url = URL(string: MasterViewController.MyVariables.urlString) {
// use url in here
let request = URLRequest(url: url)
}
Update 2:
You have your Struct which is an array of strings. Then you need to do this to get the value you want:
struct MyVariables {
static var urlString: [String]? = ["something"]
}
if let str = MyVariables.urlString?.first, let url = URL(string: str) {
// use url in here
let request = URLRequest(url: url)
print(url)
}
Right now I´m using MyVariables.urlString?.first, in the future if you want another index then you need to get that instead.
This is what I did to make it work:
let stringRepresentation = MasterViewController.MyVariables.urlString?.joined(separator:"")
print ("urlString", MasterViewController.MyVariables.urlString)
print ("sR",stringRepresentation)
let url = NSURL(string: stringRepresentation as! String)
let request = URLRequest(url: url! as URL)
myWebview.scalesPageToFit = true
myWebview.loadRequest(request)

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.

Converting URL to String and back again

So I have converted an NSURL to a String.
So if I println it looks like file:///Users/... etc.
Later I want this back as an NSURL so I try and convert it back as seen below, but I lose two of the forward slashes that appear in the string version above, that in turn breaks the code as the url is invalid.
Why is my conversion back to NSURL removing two forward slashes from the String I give it, and how can I convert back to the NSURL containing three forward slashes?
var urlstring: String = recordingsDictionaryArray[selectedRow]["path"] as String
println("the url string = \(urlstring)")
// looks like file:///Users/........etc
var url = NSURL.fileURLWithPath(urlstring)
println("the url = \(url!)")
// looks like file:/Users/......etc
In Swift 5, Swift 4 and Swift 3
To convert String to URL:
URL(string: String)
or,
URL.init(string: "yourURLString")
And to convert URL to String:
URL.absoluteString
The one below converts the 'contents' of the url to string
String(contentsOf: URL)
fileURLWithPath() is used to convert a plain file path (e.g. "/path/to/file") to an URL. Your urlString is a full URL string including the scheme, so you should use
let url = NSURL(string: urlstring)
to convert it back to NSURL. Example:
let urlstring = "file:///Users/Me/Desktop/Doc.txt"
let url = NSURL(string: urlstring)
println("the url = \(url!)")
// the url = file:///Users/Me/Desktop/Doc.txt
There is a nicer way of getting the string version of the path from the NSURL in Swift:
let path:String = url.path
2021 | SWIFT 5.1:
FOR LOCAL PATHS
String --> URL :
let url1 = URL(fileURLWithPath: "//Users/Me/Desktop/Doc.txt")
let url2 = URL(fileURLWithPath: "//Users/Me/Desktop", isDirectory: true)
// !!!!!NEVER DO THIS!!!!!!
let url3 = URL(string: "file:///Users/Me/Desktop/Doc.txt")!
// !!!!!NEVER DO THIS!!!!!!
URL --> String :
let a = String(describing: url1) // "file:////Users/Me/Desktop/Doc.txt"
let b = "\(url1)" // "file:////Users/Me/Desktop/Doc.txt"
let c = url1.absoluteString // "file:////Users/Me/Desktop/Doc.txt"
// Best solution in most cases
let d = url1.path // "/Users/Me/Desktop/Doc.txt"
FOR INTERNET URLs
String --> URL :
let url = URL(string: "https://stackoverflow.com/questions/27062454/converting-url-to-string-and-back-again")!
URL --> String :
url.absoluteString // https://stackoverflow.com/questions/27062454/converting-url-to-string-and-back-again
url.path // /questions/27062454/converting-url-to-string-and-back-again
NOTICE: pay attention to the url, it's optional and it can be nil.
You can wrap your url in the quote to convert it to a string. You can test it in the playground.
Update for Swift 5, Xcode 11:
import Foundation
let urlString = "http://ifconfig.me"
// string to url
let url = URL(string: urlString)
//url to string
let string = "\(url)"
// if you want the path without `file` schema
// let string = url.path
let url = URL(string: "URLSTRING HERE")
let anyvar = String(describing: url)
Swift 3 (forget about NSURL).
let fileName = "20-01-2017 22:47"
let folderString = "file:///var/mobile/someLongPath"
To make a URL out of a string:
let folder: URL? = Foundation.URL(string: folderString)
// Optional<URL>
// ▿ some : file:///var/mobile/someLongPath
If we want to add the filename. Note, that appendingPathComponent() adds the percent encoding automatically:
let folderWithFilename: URL? = folder?.appendingPathComponent(fileName)
// Optional<URL>
// ▿ some : file:///var/mobile/someLongPath/20-01-2017%2022:47
When we want to have String but without the root part (pay attention that percent encoding is removed automatically):
let folderWithFilename: String? = folderWithFilename.path
// ▿ Optional<String>
// - some : "/var/mobile/someLongPath/20-01-2017 22:47"
If we want to keep the root part we do this (but mind the percent encoding - it is not removed):
let folderWithFilenameAbsoluteString: String? = folderWithFilenameURL.absoluteString
// ▿ Optional<String>
// - some : "file:///var/mobile/someLongPath/20-01-2017%2022:47"
To manually add the percent encoding for a string:
let folderWithFilenameAndEncoding: String? = folderWithFilename.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
// ▿ Optional<String>
// - some : "/var/mobile/someLongPath/20-01-2017%2022:47"
To remove the percent encoding:
let folderWithFilenameAbsoluteStringNoEncodig: String? = folderWithFilenameAbsoluteString.removingPercentEncoding
// ▿ Optional<String>
// - some : "file:///var/mobile/someLongPath/20-01-2017 22:47"
The percent-encoding is important because URLs for network requests need them, while URLs to file system won't always work - it depends on the actual method that uses them. The caveat here is that they may be removed or added automatically, so better debug these conversions carefully.
Swift 3 version code:
let urlString = "file:///Users/Documents/Book/Note.txt"
let pathURL = URL(string: urlString)!
print("the url = " + pathURL.path)
Swift 5.
To convert a String to a URL:
let stringToURL = URL(string: "your-string")
To convert a URL to a String:
let urlToString = stringToURL?.absoluteString
Swift 3 used with UIWebViewDelegate shouldStartLoadWith
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let urlPath: String = (request.url?.absoluteString)!
print(urlPath)
if urlPath.characters.last == "#" {
return false
}else{
return true
}
}

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

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)