Ios 从字符串创建URL(带编码)

Ios 从字符串创建URL(带编码),ios,swift,url,encoding,nsstringencoding,Ios,Swift,Url,Encoding,Nsstringencoding,我正在尝试从字符串创建URL,如下所示 let searchParam = "?name=movies&Genre=#Action" func searchMovies(searchString: String) { let encodedString = searchParam.encodeSearchString() let urlString = "https://search.movies.local/list.html"

我正在尝试从字符串创建URL,如下所示

let searchParam = "?name=movies&Genre=#Action"

func searchMovies(searchString: String) {
    let encodedString = searchParam.encodeSearchString()
    let urlString = "https://search.movies.local/list.html" + encodedString

    guard let url = URL(string: searchParam) else {
        return
    }

    print("URL: ", url)
}

func encodeSearchString() -> String? {
  let unreserved = "#?=&"
  let allowed = NSMutableCharacterSet.alphanumeric()
  allowed.addCharacters(in: unreserved)
  return addingPercentEncoding(withAllowedCharacters: allowed as CharacterSet)
}
当搜索参数为“?name=movies&Genre=#Action”时,它可以正常工作,但如果搜索参数包含多个#,则URL为零


例如,如果searchParam为“?name=#movies&Genre=#Action”

则问题在于
字符是URL的
片段的分隔符

构建包含多个组件的URL最可靠的方法是
URLComponents
URLQueryItem
,编码是免费的

func searchMovies(with parameters: [String:String]) {
    var urlComponents = URLComponents(string: "https://search.movies.local/list.html")!
    var queryItems = [URLQueryItem]()
    for (key, value) in parameters {
        queryItems.append(URLQueryItem(name: key, value: value))
    }
    if !queryItems.isEmpty { urlComponents.queryItems = queryItems }
    print("URL: ", urlComponents.url) // https://search.movies.local/list.html?genre=%23action&name=%23movie
}


searchMovies(with: ["name":"#movie","genre":"#action"])


问题是
#
字符是URL的
片段的分隔符

构建包含多个组件的URL最可靠的方法是
URLComponents
URLQueryItem
,编码是免费的

func searchMovies(with parameters: [String:String]) {
    var urlComponents = URLComponents(string: "https://search.movies.local/list.html")!
    var queryItems = [URLQueryItem]()
    for (key, value) in parameters {
        queryItems.append(URLQueryItem(name: key, value: value))
    }
    if !queryItems.isEmpty { urlComponents.queryItems = queryItems }
    print("URL: ", urlComponents.url) // https://search.movies.local/list.html?genre=%23action&name=%23movie
}


searchMovies(with: ["name":"#movie","genre":"#action"])


改为使用URLQueryItems:
var urlComponents=urlComponents(字符串:urlString);urlComponents?.queryItems=[URLQueryItem(名称:“名称”,值:“电影”),URLQueryItem(名称:“流派”,值:“动作”);guard let url=urlComponents?.url else{return}
@Larme,谢谢。我想将查询参数作为自定义字符串传递,而不是使用URLQueryItems:
var urlComponents=urlComponents(字符串:urlString);urlComponents?.queryItems=[URLQueryItem(名称:“名称”,值:“电影”),URLQueryItem(名称:“流派”,值:“动作”);guard let url=urlComponents?.url else{return}
@Larme,谢谢。我想将查询参数作为自定义字符串传递
urlComponents.queryItems=queryItems
=>
urlComponents.queryItems=queryItems.isEmpty?nil:queryItems
否则,它将在URL末尾添加一个
,这通常不是所需的输出。@Larme说得好,谢谢。回答得好。不用说,第一种方法更可取,因为如果手动构建的字符串中有
&
(例如,搜索像“Bonnie&Clyde”这样的标题),前一种方法将失败。
urlComponents.queryItems=queryItems
=>
urlComponents.queryItems=queryItems.isEmpty?nil:queryItems
否则,它将在URL末尾添加一个
,这通常不是所需的输出。@Larme说得好,谢谢。回答得好。不用说,第一种方法更可取,因为如果手动构建的字符串中有
&
(例如,搜索类似“Bonnie&Clyde”的标题),前一种方法将失败。