1

I can get a variable in my environment but I cannot set/update the variable.

My environment object looks like this:

import SwiftUI
import Combine

class UserData: ObservableObject{
    @Published var examples = exampleData
}

I have a load function that reads in a JSON:

let exampleData: [Example] = load("exampleData.json")

Here is whaat Example is formatted as:

import SwiftUI
import CoreLocation

struct Example: Hashable, Codable, Identifiable {
    var id: Int
    var name: String
    var exampleCondition: [SubCondition]
}

struct SubCondition: Hashable, Codable, Identifiable {
    var id: Int
    var comparand: String
    var firstElement: ExampleElement
    var secondElement: ExampleElement
    
    var stringFormat: String {
        firstElement.stringFormat + " " + comparand + secondElement.stringFormat     
    }
}

struct ExampleElement: Hashable, Codable {
    var timeFrame: String
    var element: String
    
    var stringFormat: String {
        element + " (" + timeFrame + ")"
    }
}

Using @EnvironmentObject var userData: UserData in my views, I can show something like: Text(userData.examples[examplesIndex].exampleCondition[0].stringFormat)

However, I am getting a Cannot assign to property: 'stringFormat' is a get-only property. When I do:

var tempString: String = "abc"

Rectangle().onTapGesture {
   userData.examples[examplesIndex].exampleCondition[0].stringFormat = tempString
}

How do I set something within my @EnvironmentObject var userData?

Is it because I am computing stringFormat and the best way to set stringFormat is to edit the variables in ExampleElement that it uses to compute stringFormat? If so, is there a way to set up a custom get and set?

Louis Ye
  • 134
  • 1
  • 13

2 Answers2

0

To have both custom getter and setters, all you need is a second property.

var _stringFormat: String?

stringFormat: String {
    get { 
        _stringFormat ?? element + " (" + timeFrame + ")"
    }
    set {
        _stringFormat = newValue
    }
}
youjin
  • 2,147
  • 1
  • 12
  • 29
0

Here is a way to go

var stringFormat: String {
    get {
        firstElement.stringFormat + " " + comparand + secondElement.stringFormat
    }
    set {
        // parse incoming newValue String to store back into
        // firstElement, comparand, and secondElement
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690