what does "->" mean in swift when declaring functions? - ios

example function
func example(titles: [String]) `->` [UIButton] {
}
and where could i find more docs on this topic (docs relevant to functions declaring in swift)?

There is no > in swift function declarations - someone botched up the HTML rendering in the page you were reading. It was supposed to be -> (an arrow made up of a hypen and the greater than operator) that's used to denote the return type of the function.
The text was supposed to read
func example(titles: [String]) -> [UIButton] {
}
Which means the example function has one parameter called titles of type [String] (array of String) and it returns a [UIButton] (array of UIButton).

Assuming you're talking about -> the portion after that denotes the return value of the function.

Related

Difference between generic function whose return type is protocol and nongeneric function whose argument and return type are protocol

When I work on the opaque types, I read this section in the official documents of Swift.
Another problem with this approach is that the shape transformations
don’t nest. The result of flipping a triangle is a value of type
Shape, and the protoFlip(:) function takes an argument of some type
that conforms to the Shape protocol. However, a value of a protocol
type doesn’t conform to that protocol; the value returned by
protoFlip(:) doesn’t conform to Shape. This means code like
protoFlip(protoFlip(smallTriange)) that applies multiple
transformations is invalid because the flipped shape isn’t a valid
argument to protoFlip(_:).
This part made me consider about nested functions whose return type is protocol and I wanted to play about the protocol return types in the playground. As a result, I created a protocol called Example and also, a non generic and generic concrete types that conform to Example protocol. I kept "sample" method implementations which is protocol requirement as simple as possible because of focusing return types.
protocol Example {
func sample(text: String) -> String
}
struct ExampleStruct: Example {
func sample(text: String) -> String {
return text
}
}
struct ExampleGenericStruct<T: Example>: Example {
var t: T
func sample(text: String) -> String {
return t.sample(text: "\n")
}
}
After that, I created a generic function which has an argument constraint by Example protocol and returns Example protocol. Then, I tested my function as nested.
func genericTestExample<T: Example>(example: T) -> Example {
return ExampleGenericStruct(t: example)
}
genericTestExample(example: genericTestExample(example: ExampleStruct()))
I got this error:
Value of protocol type 'Example' cannot conform to 'Example'; only
struct/enum/class types can conform to protocols
This is what I expected. Function returns the protocol itself, not the concrete type that conforms it.
Finally, I wrote an another function.
func testExample(example: Example) -> Example {
if example is ExampleStruct {
return example
}
return ExampleGenericStruct(t: ExampleStruct())
}
When I run the code, I could nest this function successfully.
testExample(example: testExample(example: ExampleStruct()))
I can pass any value to both genericTestExample and testExample functions as long as it conforms to Example protocol. Also, they have the same protocol return type. I don't know why I could nest testExample function while I could not nest genericTestExample function or vise versa.
swift 5.4
2021-09-27 08:36 UTC
#ceylanburak
you should use the Opaque Types in swift.
// some Example is **Opaque Types** !!!
func genericTestExample<T: Example>(example: T) -> some Example {
return ExampleGenericStruct(t: example)
}
now follow your previous mind
genericTestExample(example: genericTestExample(example: ExampleStruct()))
and it equals to
let e1: some Example = genericTestExample(example: ExampleStruct())
genericTestExample(example: e1)

Swift 4 How to transfer functions in swift?

I have in in my app an function. Is there a way to transfer it to other Viewcontroller? if I use UserDefaults.standard.set(function(), forKey: "function")
I don't know how to load it, because
let function() = UserDefaults.standard.object(forKey: "function") as? CGFunction
doesn't work.
Thanks for answers!
Passing and returning functions
The following function is returning another function as its result which can be later assigned to a variable and called.
func jediTrainer () -> ((String, Int) -> String) {
func train(name: String, times: Int) -> (String) {
return "\(name) has been trained in the Force \(times) times"
}
return train
}
let train = jediTrainer()
train("Obi Wan", 3)
Yes, Swift allows you to pass functions or closures to other objects, since functions and closures are themselves first class objects.
However, you cannot save a function or closure to UserDefaults. To the best of my knowledge there is no way to serialize functions or closures, and in any case they certainly are not one of the very small list of types that can be saved to UserDefaults. (Known as "property list objects" since the same small set of types can be store to both property lists and to UserDefaults.)
Why do you want to pass a function to another view controller?
In Swift, functions are Closures. You can simply pass closures in code.
Class A {
var someFunction: (Int) -> String
init(f: (Int) -> String) {
someFunction = f
}
}
func f2(a: Int) -> String {
return "Value is: \(a)"
}
let AInstance = A(f: f2)
print(AInstance.someFunction(5)) // prints "Value is: 5"
or specific someFunction as optional like var someFunction: ((Int) -> String)! and set it later in code.
I'm going to answer your initial question:
I have in in my app an function. Is there a way to transfer it to other Viewcontroller?
Yes, there is a way: use your segue rather than trying to store the function in userDefaults.
1) Make sure that the destination view controller has an instance variable that can hold your function. (Note that in Swift 4, you'll have to make sure you either set a default value for that variable, or create a custom initializer to ensure the variable is given a value on initialization.)
2) In the first view controller, wherever you handle your segue, instantiate your destination view controller. Then set the variable to your function. (You can do this, for example, in an override of the prepare(for segue: UIStoryboardSegue, sender: Any?) method.)

iOS Swift 3 parameters have underscore in front

Today I opened my project in Xcode and it required to convert current Swift to Swift 3. After the conversion, I found all parameters of functions have an underscore in front. For example, func didGetWeather(_ weather: Weather) {}. I tried to take away the underscores and it worked fine. I wonder what those underscores are for.
Before swift3 the label of the first parameter by default was not listed in the function call, in swift3 does, the way to not name the parameters is placing an underscore before the parameter name in the signature, swift3 migrator add underscore the functions first parameter to not break existing code that rely on not placing the first label at function call.
As per Apple documentation:
If you don’t want an argument label for a parameter, write an underscore (_) instead of an explicit argument label for that parameter.
func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
// In the function body, firstParameterName and secondParameterName
// refer to the argument values for the first and second parameters.
}
someFunction(1, secondParameterName: 2)
If a parameter has an argument label, the argument must be labeled when you call the function.
In Swift 2, we used to declare functions like:
func myFunc(param1 param:String) {}
and we had to call it like:
myFunc(param1:)
But later Apple introduced a way to omit argument labels using underscore(_), the function declaration would be:
func myFunc(_ param:String) {}
And then we can call the function in two ways:
myFunc(_:) // when we don't want to pass any parameters
Or
myFunc(param:"some string") // when we want to pass any parameters
The first way (using _) is mostly used when we want to define a selector. For eg:
someButton.addTarget(self, action: #selector(shareCatalog(_:)), for: .touchUpInside)
Yes, its changelog in Swift 3.0.
All function parameters have labels and "_" with at first of function :
Now below all default methods also have (_).
override func viewWillAppear(_ animated: Bool)
override func didMoveToView(_ view: SKView)
func textFieldShouldReturn(_ textField: UITextField) -> Bool

Swift: syntax explanation - round brackets then "in"

I following tutorial and confused with following code:
let rectToDisplay = self.treasures.reduce(MKMapRectNull){
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in
let treasurePointRect =
MKMapRect (origin: treasure.location.mapPoint, size: MKMapSize (width: 0, height: 0))
return MKMapRectUnion(mapRect, treasurePointRect)
}
In fact, I'm not understand only that line:
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in
Is that some kind of function or something? What is the output? Im not quite understand meaning of that construction (struct: struct, someClass: someClass) -> Struct in
What is that logic? What is the meaning of "in"?
If you wondering, treasure is custom class that contain coordinate properties - latitude, longitude, etc.
I understand the "whole" meaning of that code snippet, but syntax of that line confuse me a bit..
Could you provide an explanation? Thanks a lot!
In Swift there are two ways to declare a function: with func, and with a closure expression:
// this is a function that takes an Int and returns a String
func f(i: Int) -> String { return i.description }
f(1) // returns "1"
// this is also a function that takes an Int and returns a String
let g = { (i: Int) -> String in return i.description }
g(1) // returns "1"
The latter is a closure expression – a quick way of defining a new function inline. They are most commonly used with functions that take functions (for example map, which takes an array and a function that transforms an element of that array, and runs the function on each element creating another array).
The syntax for closure expressions is they start, within braces, with arguments and return type, and then an in, and then the function body. Unlike with func, which starts with the func keyword, then the arguments and return type, followed by the function body within braces.
You don't always see the in because it can be left off. There are lots of shorthands that allow you to skip the arguments and return type (and the return keyword) altogether. But sometimes you need to give them, and then you need the in keyword.
You can read more about closure expressions in the Apple Swift book. You can read more about functions and closure basics here.

Swift Converting Character to String

I have an issue with converting character type to String type. First of all, I have below extension of String for finding nth character within String.
extension String {
func characterAtIndex(index: Int) -> Character? {
var cur = 0
for char in self {
if cur == index {
return char
}
cur++
}
return nil
}
}
I get what I want with this class extension. However when I use that nth character for title of my custom UIButton, gives an error. My Uibutton Class is
class hareketliHarfler: UIButton {
init(frame: CGRect) {
super.init(frame: frame)
// Initialization code
}
func getLetter(letter:String!){
self.titleLabel.text = letter
}
}
The error show when i try to access "getLetter(letter:String)" function. Here is example of main view Controller codes:
var harfim = hareketliHarfler(frame: CGRectMake(100,100,100,100))
var str="This is my String"
var bufi=str.characterAtIndex(3)
harfim.getLetter(bufi as AnyObject) ****
In * section I try .getLetter(bufi), .getLetter(bufi as String) also I try to change parameter type of function. Look like: func getLetter(letter:Character!) or func getLetter(letter:AnyObject!)...etc
Didn't find a way. Need a help on that. Thank you
How about the simple
String(theCharacter)
Works in Swift 4 and Swift 5
Your problem is quite simple: your characterAtIndex function returns a Character, and self.titleLabel.text is a String. You can't convert between the two implicitly. The easiest way would be to turn the Character into a String using the String initialiser:
// ch will be Character? type.
if let ch = str.characterAtIndex(3) {
// Initialise a new String containing the single character 'ch'
harfim.getLetter(String(ch))
} else {
// str didn't have a third character.
}
Unlike other solutions, this is safe for unusual Unicode characters, and won't initialise a potentially large array or iterate the whole String just to get the third character.
Change this:
var bufi=str.characterAtIndex(3)
harfim.getLetter(bufi as AnyObject)
to this:
harfim.getLetter(String(Array(str)[3]))
So what happening here:
we create an array from our string. Array elements are symbols from original string. Such break down correctly tracks symbols that are presented with a sequences of two or more code points. E.g. emoji or flag as noted by #MartinR.
We access element at 4-th position.
Note that as we crate an array from initial string then performance wise is better to use this method only with short strings and avoid it in oft-repeated routines. But in your case it seems to be OK.
Can also use Character(text).isNumber if you want to get localised numbers.
Reference:
https://developer.apple.com/documentation/swift/character/3127015-isnumber

Resources