西里尔字符在URL中

应用程序崩溃与以下url:

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 

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

非ASCII字符(和许多特殊字符)需要在我们的转义。 Chrome浏览器和其他浏览器自动执行。 他们在地址栏中find更好的显示URLs。

因此,如果您有静态url,只需将其粘贴到地址栏中,按回车键,再次select该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" 

尝试这个:

 let encodedUrl = jsonUrl.stringByAddingPercentEncodingWithAllowedCharacters(URLQueryAllowedCharacterSet) 

像这样的东西:

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

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

以Swift的Wikipedia页面为例:

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字符)。

尝试stringByAddingPercentEncodingWithAllowedCharacters:在NSString上定义。 你可能会看到人们build议stringByAddingPercentEscapesUsingEncoding: ,但是这个方法在iOS 9中已经被弃用了。

Foundation中还有一些预定义的NSCharacterSet ,比如URLHostAllowedCharacterSetURLPathAllowedCharacterSet 。 因此,如果你真的必须在代码中parsing非转义的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组件或子组件string进行百分比编码,而不是整个URLstring。

这是因为根据RFC 3986 ,不是一个URL的所有部分都可以百分比编码(例如scheme – http / https / etc)。

url不能包含西里尔文字符。 如何将西里尔文字符翻译成有效的URL有一些标准 – 如果你search“Punicode”(P是有意的),你可能会发现一些东西。

在Xamarin:

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