Restricting var to result of #keyPath() - ios

I really like an idea of using #keyPath() for safety reason. Now, I want to give my enum case an associated value with the name of some property.
My question is - are there any ways to force compilation check on associated value to give me a guarantee that this path is existed?
Though it doesn't work, what I want is something like this:
enum MissingKeysError {
case propIsMissing(checkedExistedPropertyHere: String)
}
I understand that #keyPath only returns me a string, but I really would like to use similar mechanism for my associated value.

Related

why Objective-C convert to swift wrong

why

-(void)addSimpleListener:(id<XXSimpleListener>)listener
convert to swift look like this:
func add(_ listener: XXSimpleListener?) {
}
but change the method to this

-(void)addSimpleListener:(id<XXSimpleListening>)listener

and it will convert to this
func addSimpleListener(_ listener: XXSimpleListening?){
}
Xcode (or whatever tool you are using to do the conversion) is merely following Swift API guidelines. Specifically:
Omit needless words. Every word in a name should convey salient information at the use site.
More words may be needed to clarify intent or disambiguate meaning, but those that are redundant with information the reader already possesses should be omitted. In particular, omit words that merely repeat type information.
In the first case, the words SimpleListener in addSimpleListener is repeating the type of the parameter, so they are removed from the method name. However, in the second case, SimpleListener and SimpleListening does not look the same to whatever tool you are using, so it thinks that SimpleListener should be kept.
In my (human) opinion though, I think the method should be named addListener, because:
Occasionally, repeating type information is necessary to avoid ambiguity, but in general it is better to use a word that describes a parameter’s role rather than its type.
Listener is the role of the parameter.

What is the preferred way of getting value in swift, var vs. func?

What's the preferred way of getting a value in swift?
Using a read-only variable
var getString: String? {
return "Value"
}
or using a function?
func getString() -> String? {
return "Value"
}
Also, is there a performance difference between the two?
First, neither of these would be appropriate names. They should not begin with get. (There are historical Cocoa meanings for a get prefix that you don't mean, and so even if you mean "go out to the internet and retrieve this information" you'd want to use something like fetch, but certainly not in the case you've given.)
These issues are addressed in various sections of the Swift API Design Guidelines. First, a property is a property, whether it is stored or computed. So there is no difference in design between:
let someProperty: String?
and
var someProperty: String? { return "string" }
You should not change the naming just because it's computed. We can then see in the guidelines:
The names of other types, properties, variables, and constants should read as nouns.
Furthermore, as discussed in The Swift Programming Language:
Properties associate values with a particular class, structure, or enumeration. Stored properties store constant and variable values as part of an instance, whereas computed properties calculate (rather than store) a value.
So if this is best thought of as a value associated with the type (one of its "attributes"), then it should be a property (computed or stored). If it is something that is not really "associated" with the type (something that the caller expects this type to retrieve from elsewhere for instance), then it should be a method. Again from the Design Guidelines:
Document the complexity of any computed property that is not O(1). People often assume that property access involves no significant computation, because they have stored properties as a mental model. Be sure to alert them when that assumption may be violated.
If "stored properties as a mental model" doesn't match what you mean to express, then it probably shouldn't be a property in the first place (and you need to document the discrepancies if you make it a property anyway). So, for instance, accessing a property should generally have no visible side effects. And if you read from a property immediately after writing to it, you should get back the value you wrote (again, as a general mental model without getting into the weeds of multi-threaded programming).
If you use a method, it can often result in a different appropriate name. See the "Strive for Fluent Usage" section of the Design Guidelines for more on that. There are several rules for selecting good method names. As a good example of when to use properties vs methods, consider the x.makeIterator(), i.successor() and x.sorted() examples and think about why these are methods and why they're named as they are. This is not to say there is exactly one answer in all cases, but the Design Guidelines will give you examples of what the Swift team intends.
With no discernible difference in performance, make the choice for readability:
When an attribute behaves like a variable, use a property. Your example falls into this category.
When reading an attribute changes object state, use a function. This includes
Attributes that behave like a factory, i.e. returns new objects when you access them
Attributes that produce new values, such as random number generators
Peripheral readers
Input iterators
Of course, if the attribute is computed based on one or more argument, you have no other choice but to use a function.
Just as a note: If you want to use both getters and setters in Swift you can do as follows:
var myString: String {
get {
return "My string"
}
set {
self.myPrivateString = newValue
}
}
This way you can access your value as if it was a regular variable, but you can do some "under-the-hood magic" in your getters and setters

Using enum With Integers in Swift

I'd like to know how can I limit the set of values that I can pass to function as an argument (or to class as a property). Or, in other words, the logic that I want to implement, actually, is to make function or a class accept only particular values. I've come up with an idea to use enum for it. But the caveat here is that I can't use pure integers with the 'case' like so:
enum Measure {
case 1, 2, 3
}
Is there any way to implement what I want?
enum Measure:Int{
case ONE = 1
case TWO = 2
case THREE = 3
}
//accept it as argument
func myMethod(measure:Measure){
switch measure {
case .ONE:...
case .TWO:...
case .THREE
}
}
//call the method with some raw data
myMethod(Measure(rawValue:1)!)
//or call the method with
myMethod(Measure.ONE)
But why are you trying to implement it. Swift by default does not allow to pass more or fewer arguments than defined on the definition of that function or class.
So if you have a simple function which takes just one argument, then no one can pass less or more than one argument while calling your function. And if he would try to do so then the swift compiler won't allow him/her to do so.
So logically the conclusion is you don't need to develop anything like that.
If your scenario is different then what I m thinking please let me know by adding comment or writing another question in a simpler or understandable way.

Why can I declare a variable without writing optional mark?

First of all, I believe my question is different with those questions about "what is optional in swift". Because I am asking why I can do this, not what is this.
I am new to swift. When I learn this fabulous language tonight, I got a problem that I never saw this mark-"?" in a programming language. And I searched it for a while. I know what optional binding is now.
But now I got a new question.
When I want to declare a variable that is not optional. I can write this syntax:
var friend: String
But I can't write:
var friend: String = nil
To declare a variable that is nil I can only use optional:
var friend: String? = nil
Let's see the first piece of code. When the new variable friend just be declared, its value is nil, right? Because I didn't assign any value to it. But according to the definition of optional, like the second and the third pieces of code, we can't assign nil to non-optional variables.
So my question is why I can declare a variable without optional mark but has no initial value. This question may be simple, but I really don't know why it happens.
Thanks in advance!
Swift allows you to declare a non-optional variable or constant without initializing it in the declaration, but you will have to assign it a value before using it. The value of the variable or constant is not nil (non-optionals can never be nil)--it simply has no defined value. Basically you are saying you will give it a value later, possibly based on the result of a computation or an if statement.
Swift will give you a compile-time error if you try to use a non-optional variable or constant without first assigning a value to it.
The first value you set is an uninitialized variable with the type of string.
A very common pattern in programming is to have an operation that might or might not return a value. In some languages, like javascript, when coming across a null value our program continues to operate just fine as long as our program is not dependent on that value to continue. In other languages, like java for example, a null value can cause a NullPointerException and crash our program.
Swift's solution to this problem is optionals. By default if we define a variable without a value, the compiler will complain. So, in order to declare a value that may or may not have a value at runtime, we need to add a ? which is known as “wrapping our values in an optional”. This is because we are indeed literally wrapping our value in Swifts optional type, thus giving it value. To get a better picture as to whats going on, we can look at how Swifts Optional enum.
enum Optional<T> {
case None // has no value
case Some(T) // has some value
}

Struct or Enum to use for serialization keys?

Is there any reason why Apple prefers using structs over enums in the Lister demo for declaring keys for serialization? Is there might be some benefits?
For example:
private struct SerializationKeys {
static let text = "text"
static let uuid = "uuid"
static let completed = "completed"
...
//duplicated key!
static let descriptionText = "text"
}
Here we might have potential duplicates for keys. It's not a big question for small objects (don't forget copy/paste :)), but for large objects with tens fields it can be a real problem.
With enum we don't have such a problem:
private enum SerializationKeys : String {
case text = "text"
case uuid = "uuid"
case completed = "completed"
//...
case descriptionText = "text"
//here we have compiler's warning: Raw value for enum case is not unique
}
Will be happy to hear some thoughts on this.
I do the same thing, sometimes, and here's why.
With a struct, my values are directly available: so, if SerializationKeys is a struct, then SerializationKeys.text is a string.
But with an enum, the enum is the value. If SerializationKeys is an enum, then SerializationKeys.text is not a string; it's an enum. If I want the string, I have to fetch it explicitly, as the enum's rawValue. Sometimes, that's just too nutty. On the other hand, if it's acceptable, or if there's another reason why this makes a good enum, then fine, I'll use an enum.
To put it another way: if this is just a glorified namespace for some constants, a struct with static members seems simplest. An enum is for a switch, i.e. something that needs to exist in exactly one of several possible states.
Apple's reason for choosing a struct here seems to be purely semantic. SerializationKeys.descriptionText is a property. SerializationKey.DescriptionText is a type. And it is kind of semantically weird to use a type as a key.
True, in this particular instance the SerializationKey.DescriptionText type happens to have a "raw" value associated with it. But as I understand it, raw values are really only intended to be used as a sort of "bridging layer" layer between C enums. Using it for keys like this is kind of a hack.

Resources