How to match a quiz answer to two different cases? - swift

I am making a simple personality quiz but I want some of my answers to fall under multiple personality types, not just one.
Here is working code where answers attribute to one specific PersonalityType:
var questions: [Question] = [
Question(text: "Pick one that best describes you", //Single choice answers
type: .single,
answers: [
Answer(text: "Healthy", type: .extrovert,),
Answer(text: "Average", type: .average),
Answer(text: "Unfit", type: .neuro),
]),
I want to achieve something along the lines of Answer(text: "Healthy", type: .extrovert, .fit), So that answering Healthy matches a 'extrovert' and 'fitness' personality type.
I think it's because I am using enum to record Personality Type String:
struct Answer {
var text: String
var type: PersonalityType
}
enum PersonalityType: String {
case fit = "Fitness", extrovert = "Extrovert", average = "Average", neuro = "Neuroticism" //personality type

In Answer struct use var type: [PersonalityType] instead of var type: PersonalityType.
When add answers, use like this: Answer(text: "Healthy", type: [.extrovert, .fit])

Related

How to get a property of a tuple with a string?

I'm starting in Swift, I come from JavaScript, and some things are a bit confusing for me, is there something similar to this in Swift?:
JS:
var user = {name: "Chris Answood"}
user["name"]
JavaScript doesn't have built-in tuple support. You just created an object and get the value of the name property inside this object. You have used user["name"] but user.name would also be possible.
To achieve this in Swift you can create a struct:
struct User {
name: String
}
let user = User(name: "Chris Answood")
print(user.name)
Unlike JavaScript, Swift has support for tuples. This is an easy example:
let user = (firstName: "Chris", lastName: "Answood")
print(user.firstName)

Swift equivalent of a simple JavaScript object declaration

Considering the following JavaScript object:
const car = {type:"Fiat", model:"500", color:"white"};
What would be the equivalent structure in Swift language, written in such a short line of code?
You can also do:
let car = (type: "Fiat", model: "500", color: "white")
But in my opinion, it is much cleaner to define your objects by using structs.
Swift is a strongly typed language. If you want to initialize an object, you have to define its type first. Javascript is weakly typed and apart of that it doesn't even distinguish between objects and dictionaries (or arrays).
In Swift, you could write
let car = ["type": "Fiat", "model": "500", "color": "white"]
to create a [String: String] dictionary, but that would be a bad idea in this case. Instead, you should properly declare a type:
struct Car {
let type: String
let model: String
let color: String
}
and then initialize it:
let car = Car(type: "Fiat", model: "500", color: "white")
which is almost the same as in Javascript, only with types.
Types give you more power and "shorter" does not mean "better".

Pass an empty URL as parameter in Swift

I have this array of tuplets containing strings and a url
var notifications:[(body: String, header: String, icon: URL)] = []
Now, I want to append a tuplet with an empty URL
I tried
notifications.append((body: "some text, header: "some more text", icon: nil))
but that is not allowed
What is the way to do this?
If you want to allow for icon to be nil, you need to make it optional.
var notifications:[(body: String, header: String, icon: URL?)] = []
But you really should make a struct instead of using a tuple. A struct is more powerful, gives you more options, and just better to work with.
icon has to be of type URL? (a.k.a. Optional) if you wish to be able to assign nil to it.

Why use an initializer? [duplicate]

This question already has answers here:
Why do we need to specify init method?
(3 answers)
Closed 6 years ago.
Newbie, coming from PHP. Be gentle.
Here's a swift struct with an initializer
struct Book {
let title: String
let author: String
let price: String
let pubDate: String
init(title: String, author: String, price: String, pubDate: String){
self.title = title
self.author = author
self.price = price
self.pubDate = pubDate
}
}
let HarryPotter = Book(title: "Harry Potter", author: "JK Rowling",
price: "30$", pubDate: "January 10th, 1998")
And here's a swift struct without an intializer
struct Book {
let title: String
let author: String
let price: String
let pubDate: String
}
let HarryPotter = Book(title: "Harry Potter", author: "JK Rowling",
price: "30$", pubDate: "January 10th, 1998")
If these both do the same thing, then what is the advantage of using an initializer?
In the second case, you're still using an initializer. You're using the default initializer, which was generated for you because you haven't specified any of your own.
Swift provides a default initializer for any structure or class that provides default values for all of its properties and does not provide at least one initializer itself. The default initializer simply creates a new instance with all of its properties set to their default values.
To answer the more general question of what initializes for: they encapsulate the initialization of an instance, and guarantee that you can never obtain an instance in a "half-baked" state. They're Swift's equivalent of PHP Constructors.
In your specific case, nothing, because all your initialiser is doing is setting the values. But, it's possible that you could have other code in the initialiser which actually does something.
If you want to include some logic beforehand you could do that in the constructor/initializer.
This is a bit of a guess since I'm a Ruby developer rather than Swift, but there might be times when you would want to run more (arbitrary) code inside of your initializer besides just assigning the argument values to instance variables. For example:
def initialize(attr)
#attr = attr
puts "I'm initializing!"
end
In the above case I've assigned the attribute and printed to stdout. I'm guessing in Swift all of that attribute assignment is being done automatically so if all you want to do is assign attributes you can avoid writing the initializer yourself and let Swift handle it.

How do I query for nil values with CloudKit.js?

Using CloudKit.js, how do I construct a query that matches items where a field is nil? Every permutation I've tried fails - either it's clearly matching on a string value (i.e. "null" or "nil") or it throws an error if I actually try to pass 'null'.
Any ideas? None of the below work.
filterBy: [{
fieldName: 'customerNumber',
comparator: 'EQUALS',
fieldValue: { value: "nil" }
}]
filterBy: [{
fieldName: 'customerNumber',
comparator: 'EQUALS',
fieldValue: { value: null }
}]
filterBy: [{
fieldName: 'customerNumber',
comparator: 'EQUALS',
fieldValue: { value: "null" }
}]
filterBy: [{
fieldName: 'customerNumber',
comparator: 'EQUALS',
fieldValue: { value: "" }
}]
I don't think there is any option to query for nil values in CloudKit. Also not from native code. I have tried a lot of predicates, but non seems to work.
You do have to be aware that CloudKit is a key-value store. When a value is nil, then the key won't be there in the record. There is no option to query for non existing keys.
The closest I have come to a good solution was with a predicate with the format "NOT myField => ''" sorry, don't know the format for .js
In the CloudKit CKQuery documentation there is nothing mentioned about nil fields.
In the documentation for NSPredicates there are sample's for nil values.
But it was already clear that CloudKit has implemented only a subset of the possibilities of NSPredicate (see CKQuery class reference)
I think the best way to handle this is by not using/depending on nil values. If you do need to check some nil status, then instead you could add an extra field that would represent that status.