Post

Replies

Boosts

Views

Activity

Reply to Why Store
I presume that the "Store" they refer to is in fact the App's Data Model. SwiftUI apps typically consist of a number of Views (i.e. the User Interface) and a single Data Model ("Store"), which handles all of the data processing logic. The Data Model might also interact with a server, local or external, to store and/or retrieve data. The Data Model is usually a class that adopts the ObservableObject protocol. Properties within the DataModel that change and which the User Interface (SwiftUI View(s)) needs to display, upon change, need a @Published attribute. Then, in the SwiftUI view you can monitor for changes with an @ObservedObject reference to your data model, or to a specific property of it. There are other ways of SwiftUI monitoring for changes. I also use the Data Model as an interface to an SQLite database, with SwiftUI calling a Data Model function to retrieve data from SQL, format as required, then make the data available to the SwiftUI View e.g. as an array to use in a List. This approach does not rely on monitoring for changes and works best with mostly static data. The function call is made to the Data Model within the List struct and returns the required array. This Developer reference is useful https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app Regards, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to Multiple environmentObject
I would have a single DataModel class (ObservableObject), which has your published vars for users and product. It then has functions to (e.g. getUsers) to set/update your published vars. The network call is done within the DataModel class. To promulgate a single version of the DataModel in your app, throughout the View hierarchy, you need to put @StateObject var dataModel = DataModel() in your ProjectNameApp instead of var network... Then have .environmentObject(dataModel) after ContentView() In subsequent views (e.g. ContentView) where you want to have access to dataModel put @EnvironmentObject var dataModel: DataModel after the struct definition. Within your SwiftUI Views, you can then use references to your model vars, e.g. dataModel.product If you always need to get the users, and before anything else happens, then you can put a call to getUsers() in the DataModel init(). If you don't do it this way then you'll need a call to dataModel.getUsers() somewhere else. Regards, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to Identifiable ID
You should be able to do something like ForEach(dataModel.products, id: \.productId) {product in ..... then you don't need Identifiable on your ProductModel struct, nor the var id: Int Where an entity (struct or class) does not conform to Identifiable, you have to provide the id parameter and the referenced property must be unique for each occurrence, otherwise strange things happen! The ForEach line above assumes that your products array is being supplied from a dataModel via @StateObject var dataModel = DataModel() etcetera Regards, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to Published Vars
Given that (as I understand from your previous posts) ProductModel is created from JSON, there's no need for an initalizer of the struct: the JSON decoding will do that. However, this means that "product" doesn't exist until created by your API call. The answer is to make product Optional: @Published var product : ProductModel? This requires that any reference in your code to product (e.g. in subsequent processing) must test that product exists before using it e.g. if product == nil { return } or guard let product = product else { return }. If you are absolutely sure that product exists when you come to use it you can use product! (the exclamation mark means force unwrap), but if it doesn't exist the app will crash, as you've seen before I think. Regards, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to return raw.value enum
I suggest you create a variable somewhere in your app, probably in your data model, to hold the pressed button's value e.g. var pressedButton : letters?. Then in your Button(action: { pressedButton = item }. NOTE: if pressedButton is defined outside of this view, then you need to refer to it correctly e.g. myDataModel.pressedButton pressedButton is defined as Optional, because to start with no button has been pressed. When your app goes to use pressedButton it needs to check that a button has indeed been pressed, i.e. pressedButton != nil. You can display the pressedButton value as pressedButton.rawValue There are various ways of then dealing with a change to the pressedButton, e.g 1) a didSet on the pressedButton var, 2) an @ObserverableObject entity that contains @Published pressedButton BTW, the Swift convention is that type definitions, including enums, have a name starting with Uppercase e.g. Letter and instances use an initial-lowercase name. So, in your example it would be enum Letter : String { case: a,b,c,d,e,f,g } let buttons : [[Letter]] = [     [.a, .b, .c, .d, .e, .f, .g], Best wishes, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to Image Classification Data
The answer depends on how you want to classify images and why. The first step in the process is that someone, somewhere, looks at an image and assigns a label (Classification) to it. The same image can have different labels, depending on purpose (the "why"): an image of a red Lamborghini can be classified as "Car", "Red vehicle", "Luxury sports-car" etc. Somewhere on the web there will probably be sets of images (with labels) for common classifications, such as vehicle types (car, truck, bus). However, if your purpose is to identify cars with cracked windscreens you'll probably have to create your own images and then apply labels yourself: "Not cracked", "Slightly cracked", "Badly cracked". The labelled images, whatever their source, are then used to train (create) a model using CreateML and evaluate it based on pre-assigned labels. Thereafter the output model can be used to determine the classification of any new image presented to it. For common tasks, such as determining if an image contains a face (person), there are already established models - which may or may not be publicly available, at a price or free. Such models might be compatible with CreateML and/or CoreML, directly or via some other process, in which case there's no need for you (someone) to go through the classification/training process yourself. Regards, Michaela
Aug ’21
Reply to slots to hangman game
Here's how I would do it ( maybe also with larger buttons and letter slots). Also, modify to allow different target words. Regards, Michaela //  DataModel.swift import Foundation enum Letter : String { case a = "A", b = "B", c = "C", d = "D", e = "E", f = "F", g = "G", h = "H", i = "I", j = "J", k = "K", l = "L", m = "M", n = "N", o = "O", p = "P", q = "Q", r = "R", s = "S", t = "T", u = "U", v = "V", w = "W", x = "X", y = "Y", z = "Z", sp = "  " } struct WordLetter : Identifiable {     // has to be identifiable because some words (e.g. HELLO) have non-unique letters: so can't use .self as id     var id: Int = 0     var letter: Letter = .sp } class DataModel : ObservableObject {     let buttons: [[Letter]] = [             [.a, .b, .c, .d, .e, .f, .g],             [.h, .i, .j, .k, .l, .m, .n],             [.o, .p, .q, .r, .s, .t, .u],             [.v, .w, .x, .y, .z]]     var word = "HELLO"     @Published var finished = false {         didSet {             // now do something as a result of the user completing the word e.g. give a score, congratulate etc         }     }     @Published var wordSlots = [WordLetter]() {         didSet {             // see if there are still any spaces, if so not finished             for slot in wordSlots {                 if slot.letter == .sp {                     return                 }             }             finished = true         }     }          var pressedButton : Letter? {         didSet {             // see if a button press letter is part of the word             findLetter()         }     }         init() {         // fill the Word Slots with blanks at the start - need to do this differently if you provide multiple target words         var tempSlots = [WordLetter]()  // use a temporary array to save triggering an update to the main view for each blank added         for i in (0..<word.count) {             tempSlots.append(WordLetter(id: i, letter: .sp))         }         wordSlots = tempSlots     }     func findLetter() {         for i in (0..<word.count) {             let index = word.index(word.startIndex, offsetBy: i)             guard let pressed = pressedButton else { return }             // check if a pressed letter matches a letter (or more) in the word             if String(word[index])  == pressed.rawValue {                 wordSlots[i].letter = pressed             }         }     } } import SwiftUI struct ContentView: View {     @EnvironmentObject var dataModel: DataModel     var body: some View {         VStack{             Spacer()             HStack{                 ForEach(dataModel.wordSlots) { wordLetter in                     HStack{                         Text(" ")                         Text(wordLetter.letter.rawValue)                         Text(" ")                     } .border(.blue)                 }             }                 Spacer()             ForEach(dataModel.buttons, id: \.self) {row in                 HStack{                     ForEach(row, id: \.self) {item in                         Button(action: {                             dataModel.pressedButton = item }, label: {                                     Text(item.rawValue) })                     }                 }             }             Spacer()         }     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to ObservableObject Array data not updating
I don't see where you've defined graphData, but for it to be observable it must be a class and have the ObservableObject protocol. Also, arrayInt and fooString must be properties of that class. You then need to instantiate the class and make a single copy of it available to all views. Assuming that you've created your project in a recent version of Xcode, here's an example: import SwiftUI @main struct SwiftUIExampleApp: App { // the "main" App view created by Xcode     @StateObject var graphData = GraphData(). // makes a single copy of graphData available     var body: some Scene {         WindowGroup {             GraphView() // usually refers to ContentView()                 .environmentObject(graphData). // passes a reference to the single copy of graphData down to GraphView         }     } } struct GraphView: View { // Your main view - View1     @EnvironmentObject var graphData : GraphData     var body: some View {         Text(graphData.fooString)             .padding() // **** need to invoke DetailView somehow and pass it the reference to graphView i.e. .environmentObject(graphData) ****     } } struct DetailView: View {     @EnvironmentObject var graphData : GraphData     var body: some View {         Text("This is the detail view")             .onAppear{                 graphData.appendToArray(foo: "OK", num: 21)                 // can also directly address the vars                 graphData.arrayInt.append(11)                 graphData.fooString = "Yippee"             }     } } import Foundation class GraphData : ObservableObject {. // this is your "data model"     //@Published var arrayInt = [6, 6.5]  // arrayInt contains a real (6.5)     @Published var arrayInt = [6,7]     @Published var fooString = "Name"     func appendToArray(foo: String, num: Int) {         fooString = foo         arrayInt.append(num)       } } This should work, but I haven't fully checked - it's still early here in Oz! Another approach to using GraphData, instead of @StateObject, is to make GraphData a singleton ( static let shared = GraphData() inside the class definition) then use @Published graphData = GraphData.shared Regards, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to Is it possible to update the data in my model?
The short answer is that, yes, under iOS 15 you can retrain your model using accumulated historical app data with CreateML, which provides information on the accuracy of the model. If you keep a permanent record of previous models' accuracies, then you can see how well the model performance evolves (or doesn't). However, in the example you give (choice of clothing), one has to ask what data are used to train the model? Or, more pertinently, on what basis does the user decide what to wear? Just recording the attire (pants) and colour (blue) only gives you the outputs (choices) of the process, not the inputs (reasons for wearing something). For myself, I choose my attire depending on the day's activities and the weather: maybe pantsuit if it's cold, a dress if warm. If I have a business appointment, I might choose my power colours. If lunch with girlfriends, floral. So, if your app looks at the day's appointments and the weather forecast, then offers a suggested choice of clothing, then records the actual choice(s) you have a basis for prediction. But a prediction of what? The user's mood?, because choosing a dress on a cold day isn't necessarily "wrong". In your clothing example, I don't think that CreateML & CoreML are the way to go. As you hinted at, the real issue is to give the user an informed choice of clothing depending on the circumstances. You can build up a profile of what they wear on what days, schedule, and weather and then adjust the presented suggestions accordingly - based on simple descriptive statistics (e.g. frequency). The key reason for Machine Learning is to get a predicted outcome (output) from a given set of circumstances (inputs). That prediction needs to be as accurate as possible. A good example is creating a prediction of a runner's 10K finish time from their pace, cumulative time, heart rate, etc, at each kilometre i.e. a progressive prediction ( 9 predictions in a 10KM race). If the predictions are consistently saying 36 minutes and the user finishes in 40, oops!! - the model needs retraining, with more data (factors, eg. hills). With attire, if the user chooses a red dress instead of blue, so what? Best wishes and regards, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Aug ’21
Reply to Multi-label text classification in coreML
I've wondered the same and, as a result of exploration, conclude that one has to create separate models for each label type (e.g. sentiment, subject) and then run separate predictions. If I needed a single output (array of labels) I'd probably use Combine to collect the results and notify the recipient (UI?) when all are ready. Regards, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Aug ’21
Reply to Multi-label text classification in coreML
Hello Manuel, For the same label type, I don't see a method in MLTextClassifier https://developer.apple.com/documentation/createml/mltextclassifier for associating an array of labels for a given set of text (string). So, presumably, one would have to repeat the text in the training data with each label, i.e. some text1 : label1, some text1: label2, etc For output, MLTextClassifier typically predicts one label for each text string, although there is a method predictionsWithConfidence(from: for predicting multiple possible labels and their confidence scores. CreateML and CoreML are all about identifying patterns, not looking up knowledge databases. So, if I were classifying a business by name alone, I might know that "The Jolly Swagman" is a restaurant, but there's nothing in the text that would enable such a prediction to be made. We therefore need to provide sufficient text for patterns to be evident and to be careful when manually classifying training data so as not to use knowledge, nor impose bias. I might do some more exploring and experimenting in the next few days if I get the time. Best wishes, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Aug ’21
Reply to Multi-label text classification in coreML
UPDATE: The documentation (referred to above) is confusing. To make predictions, we have to initialise an NLModel with an MLTextClassifier then call the predictedLabel or predictedLabelHypotheses method. Here's my (partial) code: // Load previously trained and saved category (label) model func loadCategoryModel() {         let modelURL = docsURL!.appendingPathComponent("CategoryModel.mlmodelc")         let modelConfig = MLModelConfiguration()         modelConfig.parameters = [:]         MLModel.load(contentsOf: modelURL, configuration: modelConfig) { result in             switch result {             case let .success(model):                 DispatchQueue.main.async {                     self.mlModel = model                 }                 self.getlatestData()             case let .failure(error):                 print("ERROR: loading model failed \(error)")             }         }     } func predictCategory(_ venue: String) -> String { // trying to predict category of an entity from the venue name (usually business name) - demo code         do {             let categoryPredictor = try NLModel(mlModel: mlModel!)             let predictedLabel = categoryPredictor.predictedLabel(for: venue) ?? "n/a"             let possibleLabels = categoryPredictor.predictedLabelHypotheses(for: venue, maximumCount: 2)             print(venue,"Predictions: ",predictedLabel,possibleLabels) // prints ==> "Costco Warehouse Predictions:  General Store ["Pharmacy": 0.17649094106070892, "General Store": 0.2769075597746391]"             return predictedLabel         } catch {                 print("ERROR: prediction failed")                 return "unknown"         }     } So, for your needs, you could train your data with multiple labels (as per earlier suggestion) then call predictedLabelHypotheses and check the probabilities provided, using those outputs (labels) that pass whatever threshold you determine. Regards, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Aug ’21
Reply to How to create ML program from Swift?
Assuming that you're targeting iOS, then you can develop apps that generate and use ML Models by using Xcode 13 (currently beta) and iOS15 (currently beta). Key documentation is here https://developer.apple.com/documentation/createml but be aware that it hasn't yet been updated to reflect the ability to create models directly in an iOS app. The main steps are: Determine what type of model you need (e.g. Text classifier, Image classifier, tabular data regression), understand your data source and collect an appropriate amount of training data, apply labels (classifications) to the training data as needs be (e.g. review text strings and apply a label to each) In your app, load the training data using a method from the CreateML framework (e.g. MLDataTable(contentsOf:) - importing from JSON or CSV is easy. How you provide the data to the device/app is another issue, eg via the bundle then to documents directory - or read-only from the bundle. Create your model from the training dataset, e..g. MLTextClassifier(trainingData: trainingData, textColumn: "MyText", labelColumn: "Category"). Check the model using an evaluation dataset (as needs be). Save the model to your documents directory then compile the model using MLModel.compileModel(at: NOTE: the resulting file has to be copied to your documents directory for later use. Put some sort of logic into your app to create the model only once, or on demand. Some models (e.g. linear regression) require a special class (MLFeatureProovider) to associate model inputs with model output. If so, create such a class in your app - ref https://developer.apple.com/forums/thread/685494 For the "normal" use of the app, load the compiled model from the documents directory (e.g. MLModel.load(contentsOf: ) and do any other initiation (e.g initialise an NLModel from the MLModel). Present data to the model for making a prediction: how this happens depends on the type of model and whether an MLFeatureProvider is required. Some models (e.g. MLTextClassifier) can provide a number of hypothetical classifications with their confidence (probability) scores for a single input request. It can be wise to use this method to check the confidence and ignore "suggestions" below a certain threshold, e.g. 50%. Regards, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Aug ’21
Reply to help me! (data sync between watch and phone)
The key documentation is here https://developer.apple.com/documentation/watchconnectivity/wcsession In essence, you need a class (can be the AppDelegate) in your iOS app that implements the WCSessionDelegate protocol, establishes a WCSession and then processes incoming watch data via func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any]). In the watch app Extension you need to create a class that adopts WCSessionDelegate, then when required create and activate a session within that class, then the class sends the information (title, number) to the phone using session.transferUserInfo(obsDict) - where session is the WCSession you instantiated and activated. In each case, don't forget to assign the delegate. There are various methods of sending data between the watch and the phone, but the above is probably the best suited to your needs. This is what I mostly use, especially if the phone app is not active at the time the watch sends the data. There's also some other housekeeping to do, such as checking that a session is active: the documentation describes this. Good luck, Michaela
Topic: App & System Services SubTopic: General Tags:
Sep ’21