Assigning a fixed value to a variable in a struct - swift

I have a struct that is used when parsing JSON data. I want one of the fields, name, to be a fixed name, see below...
struct QuestionConfiguration: Codable, DisplayOrderable {
var name: String? = "QuestionConfiguration"
var isRequired: Bool
var displayOrder: Int
var title: String = ""
var questions: [Question]
}
Each time, when I then try and access a QuestionConfiguration object, name is nil.
I have tried using an init(), with parameters and without.
I have tried String? and String.
Does anyone know how I can achieve this so that name is the same for each object, without having to pass it to the object?

Simply by changing this line - var name: String? = "QuestionConfiguration" to this - let name = "QuestionConfiguration"
Full code -
struct QuestionConfiguration: Codable, DisplayOrderable {
let name = "QuestionConfiguration"
var isRequired: Bool
var displayOrder: Int
var title: String = ""
var questions: [Question]
}
Note - If property is fixed then you should not call it as variable b'coz variable means it may change

Related

Covert ObjectId to String SwiftUI Realm object

I have my model called Restaurant:
realm object on kotlin:
class Restaurant : RealmObject {
#PrimaryKey
var _id: ObjectId = ObjectId.create()
var name: String = ""
var adress: String? = null
}
I want to use the _id property. But for that I need to convert to a String in SwiftUI
I tried: restaurant_id as! String, it does not work,
Is is related to this post: https://www.mongodb.com/community/forums/t/swift-convert-objectid-to-string/121829
No real answers there
Any other solutions?
the error when using .toHexString(): Value of type 'any Library_baseObjectId' has no member 'toHexString':
the type of _id in this case:
The error when trying: "\(restaurant._id.stringValue)"
I solved this by adding a getter to the class:
class Restaurant : RealmObject {
#PrimaryKey
var _id: ObjectId = ObjectId.create()
var name: String = ""
var adress: String? = null
fun getID() : String{
return _id.toString()
}
}
ObjectID's in Swift have a stringvalue property which returns the ObjectID as a string
You could do this
let idAsAsString = someRealmObject._id.stringValue
Or for kotlin and other SDK;s
let idAsString = object._id.toString()
In SwiftUI, the id can be accessed in a similar way, and then use the value to init a new string
let x = someRealmObject._id.stringValue
let y = String(stringLiteral: x)
let _ = print(x, y)
Text("\(x) \(y)")
and the output will be
6376886a1dbb3c142318771c 6376886a1dbb3c142318771c
in the console and the same in the Text in the UI
Here's some SwiftUI showing the use
List {
ForEach(myModel) { model in
NavigationLink(destination: SecondView(navigationViewIsActive: $navigationViewIsActive, selectedEntryToShow: model))
{
Text("\(model._id.stringValue)") //ormodel._id.toString()
}
}
}
This Swift model works perfectly and the string of ObjectId can be read per above.
class Restaurant: Object {
#Persisted(primaryKey: true) var _id: ObjectId
#Persisted var name: String = ""
#Persisted var adress: String? = null
}

Struct's id of type UUID changes everytime i try to access it [duplicate]

This question already has answers here:
SwiftUI: data identifier stability and uniqueness
(2 answers)
Closed 1 year ago.
I have a struct which is parsed from JSON, but contains another struct Article that must be identifiable. It looks like this:
import Foundation
struct TopHeadlines: Codable {
var totalArticles: Int
var articles: [Article]
struct Article: Codable {
var title: String
var description: String
var url: String
var image: String
var publishedAt: String
var source: Source
}
struct Source: Codable {
var name: String
var url: String
}
var json: Data? {
return try? JSONEncoder().encode(self)
}
}
extension TopHeadlines.Article: Identifiable {
var id: UUID { return UUID() }
}
I need UUID generated to access image from newImages dictionary:
List(viewModel.articles, id: \.id) { article in
HStack {
OptionalImage(uiImage: viewModel.newsImages[article.id])
Text(article.id.uuidString)
Text(article.id.uuidString)
Text(article.id.uuidString)
}
}
but three text views print three different UUIDs:
CC83B8AE-61B1-4A7D-A8A4-1B1E98C27CE7
545C1D28-F098-48A3-8C3C-A98BB54F9751
39B8383C-A2D8-46B0-BA51-1B861AF09762
How should I create ID for Article struct so it wouldnt be re-generated everytime?
You've declared id as a computed property, so by definition a new UUID instance will be returned every time you access the property.
You need to make the property a stored immutable property to ensure that the UUID never changes.
You also need to manually declare a CodingKey conformant enum and omit the id key from its cases to tell the compiler that id should not be decoded from the JSON.
struct TopHeadlines: Codable {
var totalArticles: Int
var articles: [Article]
struct Article: Codable, Identifiable {
var title: String
var description: String
var url: String
var image: String
var publishedAt: String
var source: Source
let id = UUID()
private enum CodingKeys: String, CodingKey {
case title, description, url, image, publishedAt, source
}
}
struct Source: Codable {
var name: String
var url: String
}
var json: Data? {
return try? JSONEncoder().encode(self)
}
}
The id property in your extension is a computed property, so a new UUID (UUID()) is generated on each call.
Since you can't have stored properties in an extension, try adding it directly to the Article struct, like this:
struct Article: Codable, Identifiable {
var id = UUID()
var title: String
var description: String
var url: String
var image: String
var publishedAt: String
var source: Source
}
This only generates a UUID when the struct is initialized.
extensions cannot store properties, that's why you've implemented id as computed property, and each new UUID() is unique
the most obvious solution is to move it to move it to your struct
struct Article: Codable {
let uuid = UUID()
// ...
}
Declared like this it won't require value both in time of decoding or creating new object.
But if you can't edit this struct(which is probably why you're using an extension), you can do the following: extend your struct with Hashable, then you can access object hashValue which is calculated based on all properties so this value will be the same only for two objects with same values in all properties, which is usually fits good for an unique identifier
extension Article: Hashable {
}
Usage
Text("\(article.hashValue)")

Why am I getting this error "Cannot assign to property: 'blurb' is a get-only property" - SwiftUI

I'm trying to assign values to a Data Object from a static array in a file called FeaturedData, but I keep getting this annoying error: "Cannot assign to property: 'blurb' is a get-only property"
Here's my Model:
struct Featured: Codable {
var tagline: String
var title: String
var blurb: String
}
Here's my ViewModel:
import SwiftUI
class FeaturedViewModel: ObservableObject {
#Published var features = [FeaturedObjectViewModel]()
var data = FeaturedData()
func setFeatured() {
for featured in data.featureds {
let featureObject = FeaturedObjectViewModel(featured: featured)
featureObject.blurb = featured.blurb
self.features.append(featureObject)
}
}
}
struct FeaturedObjectViewModel {
let featured: Featured
var tagline: String {
self.featured.tagline
}
var title: String {
self.featured.title
}
var blurb: String {
self.featured.blurb
}
}
Here's the line that's prompting the error:
featureObject.blurb = featured.blurb
I don't get what wrong.
blurb Is a computed property. You can not assign the any values. It’s always returns.
Use init for FeaturedObjectViewModel
struct FeaturedObjectViewModel {
let featured: Featured
var tagline: String = “”
var title: String = “”
var blurb: String = “”
init(featured: Featured){
self.featured = featured
self.tagline = featured.tagline
self.title = featured.title
self.blurb = featured.blurb
}
}
Note : By doing this you don’t need to do this,
featureObject.blurb = featured.blurb
It will automatically assign to object value by init.
Also, in your code with computed property, no need to reassign value to featureObject var. When you get it, it will get featured.blurb value.

SwiftUI - struct embedded in struct with UUID()

Using SwiftUI, I have a embedded struct in a struct like
struct Order Identifiable {
var id = UUID()
var includeSoap: Bool = false
var includeTowel : Bool = false
var quantity : Int
}
struct CompletedOrder Identifiable {
// var id = UUID() or var id = order.id
var order : Order
var summary : String
var purchaseDate : String
}
For later use I need to use the Identifiable keyword.
How do I avoid the extra UUID()? I can try to copy the Order.id to the CompletedOrder.id but not sure if it is a bug in XCode but I got weird errors there.
Anyway, what is the best way to do this? Do I need in both structs 'Identifiable' or is there a kind of inheritaence? What are the pro and cons about this? Again I got weird results in XCode. But I hope its me ;)
Thank you
return the order.id it self:
struct CompletedOrder: Identifiable {
var id: UUID { order.id }
var order: Order
var summary: String
var purchaseDate: String
}

Init a computed variable

I'm going to create a new class, and in this class there's a computed variable; so I'm looking for a way to init this variable:
import UIKit
class Squadra: NSCoder, NSCoding
{
var nomeSquadra: String
var numeroCoriSquadra: Int
var coloreSquadra: String
var immagineSquadra: String
var sottotitoloSquadra: String
{
get
{
return "I migliori cori: \(nomeSquadra)"
}
}
init(nome: String, numero: Int, colore: String, immagine: String, sottotitolo: String)
{
nomeSquadra = nome
coloreSquadra = colore
numeroCoriSquadra = numero
immagineSquadra = immagine
sottotitoloSquadra = sottotitolo
}
}
obviously with this line of code Xcode gives my a compile error (because the var is a get only property).
I think that i have to use a set to make the var writable, but I don't know how to operate because I don't know exactly how get and set work.
Either remove sottotitoloSquadra = sottotitolo or assign to a different variable. Even if the assignment worked, you never actually use the value that comes in as sottotitolo for anything.
I can't see useful behavior while you use independent property nomeSquadra and trying to have setter for sottotitoloSquadra at the same time. Maybe better to use hidden support property for computed variable in your case?
private var _sottotitoloSquadra: String
var sottotitoloSquadra: String
{
get
{
return "I migliori cori: \(_sottotitoloSquadra)"
}
set
{
_sottotitoloSquadra = newValue
}
}
init(nome: String, numero: Int, colore: String, immagine: String, sottotitolo: String)
{
//...
_sottotitoloSquadra = sottotitolo
}
If I understand you class correctly, you want to use the variable's default string when the init() did not provide a value (I'm just guessing though).
So if the team doesn't have a specific subTitle, you would make one up from the team's name.
I also understand that you don't want that property to be modifiable after the object is instantiated.
If that is the case, (I assume you would get an empty string for sottotitolo), you can define a private variable to hold the provided title and expose it using a computed variable. The default value (made up title) can be returned by that computed variable if a title was not supplied on the init().
class Squadra
{
var nomeSquadra: String
var numeroCoriSquadra: Int
var coloreSquadra: String
var immagineSquadra: String
private var _sottotitoloSquadra = ""
var sottotitoloSquadra: String
{
return _sottotitoloSquadra == ""
? "I migliori cori: \(nomeSquadra)"
: _sottotitoloSquadra
}
init(nome: String, numero: Int, colore: String, immagine: String, sottotitolo: String)
{
nomeSquadra = nome
coloreSquadra = colore
numeroCoriSquadra = numero
immagineSquadra = immagine
_sottotitoloSquadra = sottotitolo
}
}
Only your class, including its init() function, can modify the private variable holding the supplied sottotitolo. Outside of that source file, the private variable is not accessible at all.