Swift closure problems [duplicate] - swift

I am moving my code from Obj. C to Swift C and trying to implementing the Twitter sdk..
But, I am getting an error...
Can any body tell me what I have done wrong.
Please help me with this.
I spent 2 days tried everything but didn't work for me.

Your block does not have a return statement, therefore the compiler
uses the result of the last statement
UIApplication.sharedApplication().openURL(url)
as return value, which is a Bool and not Void as declared in the block signature.
To solve that problem, just add a return statement:
{ (url: NSURL, oauthToken: String) -> Void in
UIApplication.sharedApplication().openURL(url)
return
}

The problem is that openURL returns a boolean, and an attempt to convert it to Void is made, since the closure is declared as returning a Void. Simply remove that as follows:
{ (url: NSURL, token: String) in
UIApplication.sharedApplication().openURL(url)
}
If you don't want to change the closure signature, just assign the return value to a variable:
{ (url: NSURL, token: String) -> Void in
let ret = UIApplication.sharedApplication().openURL(url)
}

What's not stated in the other answers is that Swift will implicitly add a return to a single statement closure.
This is how statements like conditionSet.sort {$0.set < $1.set} can work.
This can also result in an unexpected error. To avoid the error, make the closure have 2 statements. The simplest way is to add a return after your original statement as stated in the accepted answer.

Related

Why does my code work on Playgrounds but not CoderPad?

I have a very simple func in Xcode playgrounds which works when I run it. But when i try to run the same code in CoderPad it gives me the following error Solution.swift:18:1: warning: result of call to 'isPalindrome(word:)' is unused
isPalindrome(word:"racecar")
Here is the code
import Foundation
func isPalindrome(word: String) -> Bool{
var oddCharacters: Set<Character> = []
for char in word {
if oddCharacters.contains(char){
oddCharacters.remove(char)
}else{
oddCharacters.insert(char)
}
}
return oddCharacters.count <= 1
}
isPalindrome(word:"racecar")
I really do not understand why this is happening.
Try this:
import Foundation
func isPalindrome(word: String) -> Bool{
var oddCharacters: Set<Character> = []
for char in word {
if oddCharacters.contains(char){
oddCharacters.remove(char)
}else{
oddCharacters.insert(char)
}
}
return oddCharacters.count <= 1
}
print(isPalindrome(word:"racecar"))
all you had to do was print it, hope this helped
That means, that the "left-hand-side" result of the call to your function isPalindrome(word: "racecar") is unused ("wasted").
It seems that for a debugging, testing, try-out environment like a Playground it's just okay to find out the result of this call (true) without storing it inside a variable. However, when doing that in other development environments, the compiler will be complaining about that. I can give you four options that would prevent the error from being thrown, just to give you a better idea of why the compiler is complaining:
If you want to use it in your further code below, just store the result and change your calling line to let isPalindrome = isPalindrome(word: "racecar"). But if you don't use it, the compiler will give you a warning again saying that you're never using your isPalindrome variable... --> Option 2
If you don't need the result, you can also just say: _ = isPalindrome(word: "racecar"). That will explicitly tell the compiler "bro, it's okay if the result is just ignored". It wouldn't make much sense for this function, though.
You can add the #discardableResult keyword prior to your function declaration, so it would say: #discardableResult func isPalindrome(word: String) -> Bool { ... That would kinda just silence your thrown error and like option 2 just tell the compiler that it's okay to just ignore the result of this function.
Just use the result in any way like:
if isPalindrome(word: "racecar") {
// do something
} else {
// do something else
}
// or
print("racecar is a palindrome: \(isPalindrome(word: "racecar")")
and everything will just be fine. I hope that helps you!

Need clarification regarding closures/completion handlers

I have been following a video tutorial, and have written the following code:
func downloadWeatherDetails(completed: ()->() ) {
let currentWeatherURL = URL(string: CURRENT_WEATHER_URL)!
Alamofire
.request(currentWeatherURL)
.responseJSON(completionHandler: { response in
let result = response.result
print(result)
})
completed()
}
So basically, my understanding is as follows. The .responseJSON handler lets you call code after the request has been fired. It allows you to specify a completionHandler, which in my case, is the closure:
{ response in
let result = response.result
print(result)
}
However, what I don't understand is what the "response" keyword actually signifies. I researched the usage of closures and saw that the syntax is:
{(param) -> returnType in { code here }
Thus, is the "response" keyword a parameter? If so, how is it being declared and where is the data coming from? How is the data passed into the "response" object? Also, why is only one parameter allowed? The code did not work if I made it as follows, for example:
{ (response, test) in
let result = response.result
print(result)
}
I would really appreciate a thorough explanation on this as I've found no help elsewhere online. I've gone through Apple's "The Swift Programming Language", a multitude of different explanations, and similar questions, but still do not understand completely.
Just to clarify, I do not believe my question is a duplicate since my question revolves primarily on the captured value stored in response rather than the syntax of closures as a whole. I went through the linked question while trying to figure out my own problem, but it did not help me sufficiently.
Minor clarification needed:
Is it always the case that when a method takes a closure as one of its parameters, for example, .testMethod(testParam: (String) -> ()) and would thus in practice be used: .testMethod(testParam: { (capturedVar) in statements} (correct me if im wrong), is it always the case that the parameter of the closure ((String) in this case) will be captured and stored in capturedVar? Will there always be data passed into the variable you define? Or is this cycle specific to alamofire?
Swift closures are defined as:
{ (parameters) -> return_type in
statements
}
That is, the names in parenthesis are the variables the closure has captured, and the -> type is the optional return type (optional because the compiler can usually infer it). Alamofire's responseJSON method captures a DataResponse<Any> parameter, which you can name whatever you want, but which is usually just named response. You can then access it inside that closure.
Also, your completed() call should be inside the responseJSON call, not outside, otherwise it just gets called immediately.

Possible in swift to do a recursive function call with javascriptcore?

I have a function that is called by javascript with JavascriptCore.
Now inside that function I have to evaluate a javascript again under a certain condition. This should call the same function.
let My_JS_Function: #convention(block) ( String, String, String ) -> ( ) = {
thing_1, thing_2, thing_3
in
let my_Condition = true
if my_Condition {
let c = JSContext()
// compiling error: "Variable used within its own initial value"
Context.setObject(unsafeBitCast(My_JS_Function, AnyObject.self), forKeyedSubscript: "My_JS_Function")
c.evaluateScript("My_JS_Function("value 1","value 2","value 3");")
}
}
Now XCode tells me:
Variable used within its own initial value
Does anybody know wheather there's a way how to solve this problem?
Maybe a way to write the My_JS_Function as a function and not like here as a variable?
I could fix the problem with avoiding having functions as properties.
Therefor I put the functionality in an extra class and used JSExport.
One example for how it can be done with JSExport can be found here.

Can you help me understand this Swift method?

I am building an app using Swift for the first time and using the AlamoFire library. I've built apps using Obj-C and AFNetworking before, but I'm having a hard time groking this Swift response method:
Alamofire.request(.GET, "http://someapi.com/thing.json")
.responseJSON { _, _, JSON, _ in
println(JSON)
}
The actual method definition is:
public func responseJSON(options: NSJSONReadingOptions = .AllowFragments, completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self {
return response(serializer: Request.JSONResponseSerializer(options: options), completionHandler: { request, response, JSON, error in
completionHandler(request, response, JSON, error)
})
}
I don't really understand what's going on here when I use this response method.
Why am I not using parens in the method call?
Am I just passing a block or anonymous function into this method?
What is the significance of passing underscores (_)?
What is the in keyword doing?
It's all here:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID102
No parens: that's trailing closure syntax. Idea is that closures can get long, hard to remember/determine long-distance paren pair.
Yes, block = anonymous function = (anonymous) closure. Yes, you're passing that as the only parameter. Since it's omitted, 'options' gets its default value of '.AllowFragments'. Trailing closure { ... } gets bound to completionHandler parameter.
The '_' is the 'don't care about this parameter' syntax ... e.g. if the function doesn't use the parameter, no point to giving it a local name.
in is part of closure syntax: indicates start of function body. Definitely read the whole closure syntax chapter above. It's designed to be extremely terse, nothing intuitive about it.

Getting a function's return type in Swift

I realize that reflection isn't fully supported (yet) in Swift, but reflection run time methods are (apparently) supported. I'm trying to get the return type of a function at run time. Here's my example
let s:Selector = "willAnimateRotation"
var m:Method = class_getInstanceMethod(object_getClass(self), s)
let returnType = method_copyReturnType(m)
println("method: \(m); returnType: \(returnType)")
free(returnType)
Here's an example of my willAnimateRotation method, currently returning String:
private func willAnimateRotation() -> String {
return "abc"
}
The output of this does not seem to vary depending on the return type of the selector. E.g., with String or Void return type for the selector, I get the following output:
method: 0x0000000000000000; returnType: 0x0000000000000000
Thoughts?
ALSO: I'm actually not really trying to do this in Swift. I'm bridging an Objective-C class to Swift, and am getting the same results there, when the Objective-C code attempts to determine the return type of a Swift selector. That is, my end-goal in this case happens to be to use Objective-C to get the return type of a Swift selector.
OK. I've figured this out. The problem comes with my use of the "private" keyword. If you drop that and just use:
func willAnimateRotation() -> String {
return "abc"
}
The sample code above works fine.
In Swift you indicate the function’s return type with the return arrow -> (a hyphen followed by a right angle bracket), which is followed by the name of the type to return.