According to this post from NSHipster, we have extended the NSURL class to initialize NSURL objects using literals like this:
// the following is a full fledged NSURL object
let url: NSURL = "http://nshipster.com/"
Unfortunately, the post was written when Swift was first announced and it no longer compiles.
I was able to get my own custom object to conform to StringLiteralConvertible, and it looked like this:
final class Dog {
let name: String
init(name: String) {
self.name = name
}
}
// MARK: - StringLiteralConvertible
extension Dog: StringLiteralConvertible {
typealias UnicodeScalarLiteralType = StringLiteralType
typealias ExtendedGraphemeClusterLiteralType = StringLiteralType
convenience init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
self.init(stringLiteral: value)
}
convenience init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
self.init(stringLiteral: value)
}
convenience init(stringLiteral value: StringLiteralType) {
self.init(name: value)
}
}
This works great. For example, the following 2 lines of code will create a Dog object:
let dog = Dog(name: "Bob")
let dog: Dog = "Bob"
Unfortunately, using this strategy via extending NSURL was met with errors:
extension NSURL: StringLiteralConvertible {
public typealias UnicodeScalarLiteralType = StringLiteralType
public typealias ExtendedGraphemeClusterLiteralType = StringLiteralType
convenience public init?(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
self.init(stringLiteral: value)
}
convenience public init?(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
self.init(stringLiteral: value)
}
convenience public init?(stringLiteral value: StringLiteralType) {
self.init(string: value)
}
}
I've been trekking through the compiler errors, solving them 1 guess at a time. However, I can't get past the following error that occurs for each of the initializers:
Initializer requirement 'init(...)' can only be satisfied by a 'required' initializer in the definition of non-final class 'NSURL'
Adding the required keyword will give the error that you may not declared required initializers within extensions.
Looking for some directions :|
Unfortunately, StringLiteralConvertible support for NSURL seems to be not possible in the current Swift version (2.2). The closest I can get is the following:
extension NSURL: StringLiteralConvertible {
public convenience init(stringLiteral value: String) {
self.init(string: value)!
}
public convenience init(extendedGraphemeClusterLiteral value: String) {
self.init(string: value)!
}
public convenience init(unicodeScalarLiteral value: String) {
self.init(string: value)!
}
}
But the compiler complains:
Playground execution failed: OS X Playground.playground:5:24: error: initializer requirement 'init(stringLiteral:)' can only be satisfied by a `required` initializer in the definition of non-final class 'NSURL'
public convenience init(stringLiteral value: String) {
^
OS X Playground.playground:3:24: error: initializer requirement 'init(extendedGraphemeClusterLiteral:)' can only be satisfied by a `required` initializer in the definition of non-final class 'NSURL'
public convenience init(extendedGraphemeClusterLiteral value: String) {
^
OS X Playground.playground:7:24: error: initializer requirement 'init(unicodeScalarLiteral:)' can only be satisfied by a `required` initializer in the definition of non-final class 'NSURL'
public convenience init(unicodeScalarLiteral value: String) {
And required initializers cannot be implemented in an extension.
We can simplify string-to-URL conversion from the other side!
extension String {
var url: NSURL? {
return NSURL(string: self)
}
}
var url = "http://google.coom/".url
print(url?.scheme) // Optional("http")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With