Swift Function with Args... Pass to Another Function with Args

Swift function with args... pass to another function with args

Similar as in (Objective-)C, you cannot pass a variable argument list
directly to another function. You have to create a CVaListPointer
(the Swift equivalent of va_list in C) and call a function which
takes a CVaListPointer parameter.

So this could be what you are looking for:

extension String {
func getLocalizeWithParams(args : CVarArgType...) -> String {
return withVaList(args) {
NSString(format: self, locale: NSLocale.currentLocale(), arguments: $0)
} as String
}
}

withVaList() creates a CVaListPointer from the given argument list
and calls the closure with this pointer as argument.

Example (from the NSString documentation):

let msg = "%@:  %f\n".getLocalizeWithParams("Cost", 1234.56)
print(msg)

Output for US locale:

Cost:  1,234.560000

Output for German locale:

Cost:  1.234,560000

Update: As of Swift 3/4/5 one can pass the arguments to

String(format: String, locale: Locale?, arguments: [CVarArg])

directly:

extension String {
func getLocalizeWithParams(_ args : CVarArg...) -> String {
return String(format: self, locale: .current, arguments: args)
}
}

pass existing function as parameter to another function in Swift 3

Parameter values are lets by default (and can't be mutated). This is the cause of your error message - it has nothing to do with being the result of toPassAsParam(). You can get around this one of two ways, depending if you actually want to change param1 outside of the function.

If you do want param1 to mutate and keep its new value, declare it as an inout [String:String] (the inout keyword means it can be mutated from in the function).

If you just want to be able to change it inside the function, you can just say var param1 = param1 in the first line of your function (copy it to a variable).

A little more on the subject line of your question: you aren't passing a function as a parameter. You're passing one function's return value as a parameter to another function. If you wanted to pass the actual function to createDictionaryFromParams, it would look something like:

// note the type of `function`
func createDictionaryFromParams(function: () -> [String:String],
param2: String,
param3: String) -> [String:String] {
var param1 = function() // now that we passed `function` in, we can call it to get a [String:String]
param1["name"] = "John"
param1["university"] = param2
return [:]
}

Passing in variable number of args from one function to another in Swift

sumOf and averageOf both take a variadic paramter of Int, which is not the same as an Array of Int. The variadic paramter is converted into an Array, though which is what numbers it, but then you aren't able to call sumOf on numbers.

You can fix this by making a sumOf function that takes a variadic parameter and one that takes an arrary like this:

func sumOf(numbers: Int...) -> Int {
return sumOf(numbers)
}
func sumOf(numbers: Int[]) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}

How to pass values or data between two function with parameters in swift?

Actually I didn't understand properly your problem. But as i understand that you can use this.

func firstFunc(lat: Double, long: Double) {
//do something
secondFunc(lat: lat, long: long)
}

func secondFunc(lat: Double, long: Double) {
//do something
}

But if you want to use values after process from secondFunc you can use inout parameters.

func firstFunc(lat: Double, long: Double) {
//do something
var newLat = lat
var newLong = long
secondFunc(lat: &newLat, long: &newLong)
//new values for newLat and newLong after secondFunc
}

func secondFunc(lat: inout Double, long: inout Double) {
//do something
}

How to set a function as function argument in Swift 3

Yes you can pass a function/closure as parameter of another function.

This is the syntax

func doSomething(closure: () -> ()) {
closure()
}

here the function doSomething receives as parameter a closure with no params and no return type.

You can call doSomething with this syntax

doSomething(closure: { _ in print("Hello world") })

Or using the trailing closure syntax

doSomething { 
print("Hello world")
}

Why to pass function as an argument to other function, if we can simply call it for implementation?

The reason to take a function as an argument is that it makes your function more flexible. It lets the caller decide what plus does by passing a function or closure that combines two Int values to return an Int value.

For instance, suppose the caller wants plus to multiply the values:

print(averageArg(*, 5, 6))
15

or take the max of the two values (by passing a closure):

print(averageArg({ max($0, $1) }, 1, 100))
50

A better example of this is the Swift function sorted(by:). sorted takes a closure which determines what areInIncreasingOrder means. This allows you to sort an array in increasing and decreasing order by just changing the function passed:

[1, 3, 2, 4].sorted(by: <)
[1, 2, 3, 4]
[1, 3, 2, 4].sorted(by: >)
[4, 3, 2, 1]

Here's an example using a function:

func shortNamesFirst(_ name1: String, _ name2: String) -> Bool {
if name1.count < name2.count {
return true
} else if name1.count > name2.count {
return false
} else {
// when names are the same length, sort
// them alphabetically
return name1 < name2
}
}

["Chuck", "Bob", "Bill", "Jo", "Ed", "Alexander"].sorted(by: shortNamesFirst)
["Ed", "Jo", "Bob", "Bill", "Chuck", "Alexander"]

The author of sorted doesn't have to provide a different version of sorted for every type of ordering a user might want. The user gets to decide what sorted means to them.

Is it possible to call a function as a parameter of another function in Swift?

Because in Swift functions are first-class types, you can pass it as an argument to another function.

Example:

func testA() {
print("Test A")
}

func testB(function: () -> Void) {
function()
}

testB(testA)

Pass function argument into selector in Swift

You can find the answer in your question :)
Simply use Selector parameter type, and no need #selector()

    func createDoneButton(txtField: UITextField, donePressed: Selector){
let toolbar = UIToolbar() // create toolbar
toolbar.sizeToFit() // toolbar fits the size of the screen

let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: donePressed) // action when the done button was pressed
toolbar.setItems([doneBtn], animated: true)
txtField.inputAccessoryView = toolbar
}

How to pass arguments into a function with completion swift

Your function 'apiRequest' has 2 parameters:

  1. search: String (this parameter expects a String)
  2. completion: @escaping (Result) -> ()

So when you call this method, you will pass these 2 parameters as well, like this:

.onTapGesture {
API().apiRequest(search: "String you want to pass", completion: { (result) in
self.result = result
})
}

Learn about closures, as this completion parameter is also a type of closure (escaping closure).

Passing functions as parameters in Swift

Oneword answer for your question is Closures

The Default Syntax for closures is () -> ()

Instead of Selector you could directly mention the method definition

func showConfirmBox(msg:String, title:String,
firstBtnStr:String, firstSelector:(sampleParameter: String) -> returntype,
secondBtnStr:String, secondSelector:() -> returntype,
caller:UIViewController) {
//Your Code
}

But using this will create readability problems so i suggest you to use typeAlias

typealias MethodHandler1 = (sampleParameter : String)  -> Void
typealias MethodHandler2 = () -> Void

func showConfirmBox(msg:String, title:String,
firstBtnStr:String, firstSelector:MethodHandler1,
secondBtnStr:String, secondSelector:MethodHandler2) {

// After any asynchronous call
// Call any of your closures based on your logic like this
firstSelector("FirstButtonString")
secondSelector()
}

You can call your method like this

func anyMethod() {
//Some other logic

showConfirmBox(msg: "msg", title: "title", firstBtnStr: "btnString",
firstSelector: { (firstSelectorString) in
print(firstSelectorString) //this prints FirstButtonString
},
secondBtnStr: "btnstring") {
//Invocation comes here after secondSelector is called

}
}


Related Topics



Leave a reply



Submit