URL中的西里尔符号

时间:2016-02-02 08:36:45

标签: ios swift nsurl

应用程序与以下网址崩溃:

let jsonUrl = "http://api.com/алматы/events"
let session = NSURLSession.sharedSession()
let shotsUrl = NSURL(string: jsonUrl)
let task = session.dataTaskWithURL(shotsUrl!)

日志:

fatal error: unexpectedly found nil while unwrapping an Optional value

这是因为网址中的西里尔符号。我该如何解决这个问题。谢谢你的帮助!

7 个答案:

答案 0 :(得分:6)

快捷键4
使用字符串扩展 创建一个名为 String + Extension.swift 的快捷文件,并粘贴此代码

import UIKit
extension String{
    var encodeUrl : String
    {
        return self.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
    }
    var decodeUrl : String
    {
        return self.removingPercentEncoding!
    }
}

并按以下方式使用它:(根据问题取样):

"http://api.com/алматы/events".encodeUrl

答案 1 :(得分:4)

试试这个:

let encodedUrl = jsonUrl.stringByAddingPercentEncodingWithAllowedCharacters(URLQueryAllowedCharacterSet)

答案 2 :(得分:2)

非ASCII字符(以及许多特殊字符)需要在URL中进行转义。 Chrome和其他浏览器会自动执行此操作。并且它们可以取消地址栏中的URL以获得更好的显示效果。

因此,如果您有静态网址,只需将其粘贴到地址栏中,按回车键,再次选择该网址,然后将其复制并粘贴到您的应用中:

所以而不是:

let jsonUrl = "http://api.com/алматы/events"

你会得到:

let jsonUrl = "http://api.com/%D0%B0%D0%BB%D0%BC%D0%B0%D1%82%D1%8B/events"

答案 3 :(得分:2)

这样的事情:

let apiHost = "http://api.com/"
let apiPath = "алматы/events"
let escapedPath = apiPath.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
let url = NSURL(string: "\(apiHost)\(escapedPath!)")

显然你应该做一些更聪明的事情,而不仅仅是强行打开escapedPath

以Swift的维基百科页面为例:

https://ru.wikipedia.org/wiki/Swift_(язык_программирования)变为https://ru.wikipedia.org/wiki/Swift_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F),当粘贴到浏览器中时会将您带到正确的页面(大多数浏览器都会方便地为您呈现UFT-8字符)。

答案 4 :(得分:1)

尝试在NSString上定义stringByAddingPercentEncodingWithAllowedCharacters:。您可能会看到人们建议stringByAddingPercentEscapesUsingEncoding:,但该方法在iOS 9中已弃用。

基金会中还有一些预定义的NSCharacterSet,例如URLHostAllowedCharacterSetURLPathAllowedCharacterSet。因此,如果您真的必须在代码中解析未转义的URL(使用预处理的URL,在接受的答案中提到,通常是一个更好的主意),您可以编写这样的辅助方法:

import Foundation

func url(scheme scheme: String, host: String, path: String) -> NSURL? {
    let components = NSURLComponents()
    components.scheme = scheme
    components.host = host.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
    components.path = path.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())
    return components.URL
}

// evaluates to http://api.com/%25D0%25B0%25D0%25BB%25D0%25BC%25D0%25B0%25D1%2582%25D1%258B/events
url(scheme: "http", host: "api.com", path: "/алматы/events")

请注意,上述文档提到了

  

此方法旨在对URL组件或子组件字符串进行百分比编码,而不是整个URL字符串。

这是因为根据RFC 3986,并非网址的所有部分都可以进行百分比编码(例如scheme - http / https / etc。)

答案 5 :(得分:-1)

网址不能包含西里尔字符。有标准如何将西里尔字符转换为有效的URL - 如果您搜索" Punicode" (P是故意的)。

答案 6 :(得分:-1)

xamarin中的

var uri = new Uri (url);
var nsurl = new NSUrl (uri.GetComponents (UriComponents.HttpRequestUrl, UriFormat.UriEscaped));
UIApplication.SharedApplication.OpenUrl (nsurl);