Implementing Stringliteralconvertible on Nsurl

Implementing StringLiteralConvertible on NSURL

The problem is related to your extension not conforming to the protocol. If you CMD+Click on the StringLiteralConvertible protocol, to follow it to it's definition, you will find that the typealias StringLiteralType and typealias ExtendedGraphemeClusterLiteralType are set to String.

That being said, you should modify your extension to the following:

extension NSURL : StringLiteralConvertible {

class func convertFromStringLiteral(value: String) -> Self
{
//do what you were going to do
return self()
}

class func convertFromExtendedGraphemeClusterLiteral(value: String) -> Self{
//do what you were going to do
return self()
}
}

Information about typealias is described in "The Swift Programming Language" book from pages 606-609, under the section Associated Types.

NSURL extension to adopt StringLiteralConvertible

StringLiteralConvertible support

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.

Alternative solution

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")

Is it possible to conform to StringLiteralConvertible with an enum?

The StringLiteralConvertible protocol has changed and the convertFromStringLiteral
function does not exist anymore.

You already have the required initializers. The error is that you don't assign a value to self. Example implementation:

enum Component: StringLiteralConvertible {
case Static(String)
case AnyInt

init(stringLiteral value: String) {
self = Static(value)
}

init(extendedGraphemeClusterLiteral value: String) {
self = Static(value)
}

init(unicodeScalarLiteral value: String) {
self = Static(value)
}
}

let comp : Component = "Foo"

Swift 3/4 update:

enum Component: ExpressibleByStringLiteral {
case `static`(String)
case anyInt

init(stringLiteral value: String) {
self = .static(value)
}
}

let comp: Component = "Foo"

Cannot invoke 'init' with argument list of type StringLiteralConvertible

You've got the wrong data type in your call to TextMessage init, should be NSDate()

let msg = TextMessage(id: "", host: host, target: target, time: NSDate(), text: "")

NSString? is not convertible to 'StringLiteralConvertible' & ?! in Swift

? and ! for variables:
? is used when the the variable could be an object or can be nil.
! is used when the variable could be an object or can be nil BUT it should never be nil. This prevents the coder from having to unwrap it everytime.

? and ! for casting:
"x as? y" checks if the "x" CAN be casted as "y" AND it if so it WILL be casted as "y".
"x as! y" forces the cast from x to y

So in your code you should check as? String, because it seems like you are trying to cast it later on anyway to String. So try this:

    if collectionElement != nil{

if let elementName = collectionElement["elementName"] as? String{
elementTitle.text = elementName
}
...

query.whereKey("fileCollectionElement", equalTo:collectionElement!)
}

As for the error when you index countElements, this could return a nil value so you should make sure the two sides agree on the type they working with. if countElements contains an optional (PFObject?) then make sure cell.collection element is an optional (PFObject?) also.

Having the same exact types is crucial in Swift.

Issue with NSURLSession returning tuple

Your code has error in it. If you look at it carefully you are returning from inside a closure which expects a return value of Void. That is what the error is about,

'(StringLiteralConvertible, StringLiteralConvertible, StringLiteralConvertible)' and '()' 

The type '()' means it is a void type that is expected.

So, where is your mistake,

In your dataTaskWithURL method, the closure looks like this,

{ (data, response, error) -> Void in
if error != nil{
print(error?.localizedDescription)

return ("","","")
}
}

The closure expects the Void type to be returned, but you return tuple of string.

One of the thing that is bad about the code above is about asynchronous code execution. The dataTask runs asynchronously and returns immediately, so you cannot return value of it. You should rather use some completion block to get the result after the call has completed.

I would suggest you to restructure it it the following,

func downloadContent(completion: (title : String, message : String ,buttonText : String)? -> Void){
let url = NSURL(string: websitePath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) { (data, response, error) -> Void in
if error != nil{
print(error?.localizedDescription)
}

completion((title: "", message: "", buttonText: ""))
}

task.resume()
}

NSFontAttributedString worked before XCode 6.1

Xcode 6.1 comes with Swift 1.1 that supports constructors that can fail. UIFont initialisation can fail and return nil. Also use string: when creating NSAttributedString:

if let font = UIFont(name: "Voyage", size: 20.0) {
let timeFont = [NSFontAttributeName:font]
var attrString3 = NSAttributedString(string: "(Time)", attributes : timeFont)
}


Related Topics



Leave a reply



Submit