Post

Replies

Boosts

Views

Activity

Reply to TabularData Framework: DataFrame as a List in SwiftUI
Ah, fixed it :). All I needed to do was add protocol compliance in an extension for DataFrame.Rows extension DataFrame.Rows : RandomAccessCollection { }. Then use the index property of rows as the id in the SwiftUI ForEach (or List) with yourDataFrame.rows as the source, handling the optionals as required. Cheers, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21
Reply to Create Instance of class
products is created as an empty array of type ProductModel, I.e. no product (ProductModel) has yet been instantiated. You will need to look at the definition of ProductModel to see what is required for initiation. You can do this in Xcode (jump to Definition), or autocomplete will probably prompt for the required/available parameters.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21
Reply to swift ui
Best to start at this Developer document https://developer.apple.com/documentation/swiftui When I started with SwiftUI, my biggest challenge was in rethinking state and data flow, i.e. creation and manipulation of data, which is now well covered here https://developer.apple.com/documentation/swiftui/state-and-data-flow Although SwiftUI has a lot of inbuilt management of state changes, for complex data models I now use Combine to control what gets published from the data model and when, picking up changes by an onReceive in SwiftUI views. To my mind, the key to SwiftUI is a well designed data model, where all data creation and manipulation is done in the model (using Swift) and SwiftUI only presents data, from a single source of truth data model, to the user. Where the user enters data in SwiftUI, this is handed off to the model, by bindings, for processing. Good luck! Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’21
Reply to Activity recognition using core motion
Here's some sample code using a Data Model and SwiftUI **** The Data Model import Foundation import CoreMotion class DataModel : ObservableObject {     var activityManager : CMMotionActivityManager?     @Published var activities = [CMMotionActivity] () // (remove the space before the ()     init() {         if !CMMotionActivityManager.isActivityAvailable() {             print("Activity Monitoring not available")             return         }         activityManager = CMMotionActivityManager()         if activityManager == nil {  // check just to be sure initialised OK             print("Unable to initialise Activity Manager")             return         }         activityManager!.startActivityUpdates(to: OperationQueue.main) { (motion) in             guard let newMotion = motion else { return }             self.activities.append(newMotion)         }     } } extension CMMotionActivity {     func activityString() -> String {         // returns a compound string of activities e.g. Stationary Automotive         var output = ""         if stationary { output = output + "Stationary "}         if walking { output = output + "Walking "}         if running { output = output + "Running "}         if automotive { output = output + "Automotive "}         if cycling { output = output + "Cycling "}         if unknown { output = output + "Unknown "}         return output     } } **** The Main App (if generated in Xcode 12+) import SwiftUI @main struct Activity_TrackerApp: App {     @StateObject var dataModel = DataModel()     var body: some Scene {         WindowGroup {             ContentView()                 .environmentObject(dataModel)         }     } } **** The Content View import SwiftUI struct ContentView: View {     @EnvironmentObject var dataModel: DataModel     var body: some View {         ScrollView {             ForEach(dataModel.activities, id:\.startDate) {activity in                 HStack{                     Text(activity.startDate, style: .date)                     Text(activity.startDate, style: .time)                     Text(activity.activityString())                 }             }         }     } } You must also add a Plist key for Privacy - Motion Usage Description and say why you're recording activity. This is a very rough UI, but it should get you started. You'll also need (??) to turn off monitoring at some point and deal with entering and exiting background mode. Good luck and regards, Michaela
Topic: App & System Services SubTopic: Hardware Tags:
Jul ’21
Reply to How to develop the server of app ?
I'm not sure if I've understood you correctly (maybe you're after App Store Server information), but here goes: SwiftUI apps typically consist of a number of Views (i.e. the User Interface) and a single Data Model, which handles all of the data processing logic. The Data Model might also interact with a server to store and/or retrieve data. One of my complex apps has servers for SQLite, iCloud, BlueTooth devices and Home Appliances. The Data Model handles all of these servers, consolidating data as required for use by the SwftUI View(s). The Data Model acts as the single point of truth throughout the app: all SwiftUI Views should normally get their UI output from the Data Model and provide UI input (e.g. keyboard input) to the Data Model for processing. SwiftUI monitors for changes to the Data Model, according to developer specified configuration, in order to update the relevant View(s). A simple example of this arrangement is in my answer to this post https://developer.apple.com/forums/thread/685018, which uses Core Motion data to report user activity. The @StateObject var dataModel = DataModel() line in the App View ensures that there's only one copy of dataModel throughout the app, provided conventions for .environmentObject(dataModel) are followed. This Developer document https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app describes how to manage Model Data. Regards, Michaela
Jul ’21
Reply to CreateML on iOS
As of iOS 15 (beta), CreateML can be used within an app to create (or replace) a model within the app, with access to prediction accuracy to determine whether the latest training improves on a previous model.  This requires Xcode 13 (beta) and Mac OS Monterey (beta).  There's also a new TabularData framework that works similarly to CreateML for data input (e.g. from CSV), but appears to have expanded features (not that I've explored them all). CreateML is a set of types and methods for ingesting data, preprocessing those data (e.g. filtering, mapping, transforming), then using the data for training models. Typically, a user would not be aware that these actions are taking place, so it's not, strictly speaking, a UI (i.e there's nothing on-screen). TabularData is an alternative to CreateML's ingestion and preprocessing features, although there are some annoying issues (beta??). I'm trying this out (e.g. time prediction) with a running app that I've developed over the years, and for which I have a lot of historical data. It makes sense to retrain the model after running a new course and also every few weeks as the user improves (or, in my case, degrades). Good luck and regards, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Jul ’21
Reply to User Activity Recognition
With your activityManager (CMMotionActivityManager instance in your Data Model) do a query when an app is restarted ref https://developer.apple.com/documentation/coremotion/cmmotionactivitymanager/1615929-queryactivitystarting HOWEVER, only the last 7 days of activity are available - and you'd need to know when the app was terminated or suspended so as not to double count. It might also be possible to schedule a batch background task (e.g. at night) to run the query and place results in permanent data storage. Check out this reference https://developer.apple.com/documentation/backgroundtasks/choosing_background_strategies_for_your_app particularly"Wake Your App with a Background Push". I've never done this, only knowing about it from the documentation. Good luck and regards, Michaela
Topic: App & System Services SubTopic: Hardware Tags:
Jul ’21
Reply to Is it possible to connect my headphones from swift code?
It’s possible to connect to non-BLE devices in iOS with Swift using the External Accessory framework. However, to interact with the device and send/receive data requires detailed knowledge of the manufacturer’s device specifications - which are usually not available. For example, I wanted to connect to a blood pressure monitor via a Swift app, but the device required a sign-in process and the manufacturer refused to provide documentation - probably because their own app collected and stored user data on the company’s server. good luck and regards, Michaela
Topic: App & System Services SubTopic: Core OS Tags:
Jul ’21
Reply to TabularData: DataFrame - parsing JSON array that is not at the root level
I decided to go with stripping the extraneous data, so created a String extension: extension String {     func midString(from: String, to: String) -> String {         guard let firstChar = firstIndex(of: "[") else { return "" }         guard let lastChar = lastIndex(of: "]") else { return ""}         return String(self[firstChar...lastChar])     } } get the JSON array with: let newJSON = jsonStr?.midString(from: "[", to: "]") This function is useful whenever there are header and footer surrounding a delimited array e.g. delimiters "{" and "}" NOTE: I use lastIndex(of: "]" ) in the hope that Swift is smart enough to scan from the end backwards towards the start of the array. Cheers, Michaela
Topic: Programming Languages SubTopic: Swift Tags:
Jul ’21
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 TabularData Framework: DataFrame as a List in SwiftUI
Ah, fixed it :). All I needed to do was add protocol compliance in an extension for DataFrame.Rows extension DataFrame.Rows : RandomAccessCollection { }. Then use the index property of rows as the id in the SwiftUI ForEach (or List) with yourDataFrame.rows as the source, handling the optionals as required. Cheers, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Create Instance of class
products is created as an empty array of type ProductModel, I.e. no product (ProductModel) has yet been instantiated. You will need to look at the definition of ProductModel to see what is required for initiation. You can do this in Xcode (jump to Definition), or autocomplete will probably prompt for the required/available parameters.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to swift ui
Best to start at this Developer document https://developer.apple.com/documentation/swiftui When I started with SwiftUI, my biggest challenge was in rethinking state and data flow, i.e. creation and manipulation of data, which is now well covered here https://developer.apple.com/documentation/swiftui/state-and-data-flow Although SwiftUI has a lot of inbuilt management of state changes, for complex data models I now use Combine to control what gets published from the data model and when, picking up changes by an onReceive in SwiftUI views. To my mind, the key to SwiftUI is a well designed data model, where all data creation and manipulation is done in the model (using Swift) and SwiftUI only presents data, from a single source of truth data model, to the user. Where the user enters data in SwiftUI, this is handed off to the model, by bindings, for processing. Good luck! Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’21
Reply to Activity recognition using core motion
Here's some sample code using a Data Model and SwiftUI **** The Data Model import Foundation import CoreMotion class DataModel : ObservableObject {     var activityManager : CMMotionActivityManager?     @Published var activities = [CMMotionActivity] () // (remove the space before the ()     init() {         if !CMMotionActivityManager.isActivityAvailable() {             print("Activity Monitoring not available")             return         }         activityManager = CMMotionActivityManager()         if activityManager == nil {  // check just to be sure initialised OK             print("Unable to initialise Activity Manager")             return         }         activityManager!.startActivityUpdates(to: OperationQueue.main) { (motion) in             guard let newMotion = motion else { return }             self.activities.append(newMotion)         }     } } extension CMMotionActivity {     func activityString() -> String {         // returns a compound string of activities e.g. Stationary Automotive         var output = ""         if stationary { output = output + "Stationary "}         if walking { output = output + "Walking "}         if running { output = output + "Running "}         if automotive { output = output + "Automotive "}         if cycling { output = output + "Cycling "}         if unknown { output = output + "Unknown "}         return output     } } **** The Main App (if generated in Xcode 12+) import SwiftUI @main struct Activity_TrackerApp: App {     @StateObject var dataModel = DataModel()     var body: some Scene {         WindowGroup {             ContentView()                 .environmentObject(dataModel)         }     } } **** The Content View import SwiftUI struct ContentView: View {     @EnvironmentObject var dataModel: DataModel     var body: some View {         ScrollView {             ForEach(dataModel.activities, id:\.startDate) {activity in                 HStack{                     Text(activity.startDate, style: .date)                     Text(activity.startDate, style: .time)                     Text(activity.activityString())                 }             }         }     } } You must also add a Plist key for Privacy - Motion Usage Description and say why you're recording activity. This is a very rough UI, but it should get you started. You'll also need (??) to turn off monitoring at some point and deal with entering and exiting background mode. Good luck and regards, Michaela
Topic: App & System Services SubTopic: Hardware Tags:
Replies
Boosts
Views
Activity
Jul ’21
Reply to TabularData DataFrame writeCSV changes double to string for numbers >= 1000
Fixed as of Xcode 13.0 beta 3 (13A5192j) and MacOS 12.0 Beta 21A5284e ( don't know about iOS etc, haven't tried yet). Thank you Engineers. Regards, Michaela
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jul ’21
Reply to How to develop the server of app ?
I'm not sure if I've understood you correctly (maybe you're after App Store Server information), but here goes: SwiftUI apps typically consist of a number of Views (i.e. the User Interface) and a single Data Model, which handles all of the data processing logic. The Data Model might also interact with a server to store and/or retrieve data. One of my complex apps has servers for SQLite, iCloud, BlueTooth devices and Home Appliances. The Data Model handles all of these servers, consolidating data as required for use by the SwftUI View(s). The Data Model acts as the single point of truth throughout the app: all SwiftUI Views should normally get their UI output from the Data Model and provide UI input (e.g. keyboard input) to the Data Model for processing. SwiftUI monitors for changes to the Data Model, according to developer specified configuration, in order to update the relevant View(s). A simple example of this arrangement is in my answer to this post https://developer.apple.com/forums/thread/685018, which uses Core Motion data to report user activity. The @StateObject var dataModel = DataModel() line in the App View ensures that there's only one copy of dataModel throughout the app, provided conventions for .environmentObject(dataModel) are followed. This Developer document https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app describes how to manage Model Data. Regards, Michaela
Replies
Boosts
Views
Activity
Jul ’21
Reply to What is the simplest approach to execute a Swift statement only after an asynchronous operation finishes?
You can also use Combine, which has various ways of dealing with your scenario - especially if the filtering also needs to be done asynchronously. I use Combine a lot with SwiftUI apps, because Combine’s Publishers can trigger a SwiftUI View’s .onReceive.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jul ’21
Reply to CreateML on iOS
As of iOS 15 (beta), CreateML can be used within an app to create (or replace) a model within the app, with access to prediction accuracy to determine whether the latest training improves on a previous model.  This requires Xcode 13 (beta) and Mac OS Monterey (beta).  There's also a new TabularData framework that works similarly to CreateML for data input (e.g. from CSV), but appears to have expanded features (not that I've explored them all). CreateML is a set of types and methods for ingesting data, preprocessing those data (e.g. filtering, mapping, transforming), then using the data for training models. Typically, a user would not be aware that these actions are taking place, so it's not, strictly speaking, a UI (i.e there's nothing on-screen). TabularData is an alternative to CreateML's ingestion and preprocessing features, although there are some annoying issues (beta??). I'm trying this out (e.g. time prediction) with a running app that I've developed over the years, and for which I have a lot of historical data. It makes sense to retrain the model after running a new course and also every few weeks as the user improves (or, in my case, degrades). Good luck and regards, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jul ’21
Reply to User Activity Recognition
With your activityManager (CMMotionActivityManager instance in your Data Model) do a query when an app is restarted ref https://developer.apple.com/documentation/coremotion/cmmotionactivitymanager/1615929-queryactivitystarting HOWEVER, only the last 7 days of activity are available - and you'd need to know when the app was terminated or suspended so as not to double count. It might also be possible to schedule a batch background task (e.g. at night) to run the query and place results in permanent data storage. Check out this reference https://developer.apple.com/documentation/backgroundtasks/choosing_background_strategies_for_your_app particularly"Wake Your App with a Background Push". I've never done this, only knowing about it from the documentation. Good luck and regards, Michaela
Topic: App & System Services SubTopic: Hardware Tags:
Replies
Boosts
Views
Activity
Jul ’21
Reply to Is it possible to connect my headphones from swift code?
It’s possible to connect to non-BLE devices in iOS with Swift using the External Accessory framework. However, to interact with the device and send/receive data requires detailed knowledge of the manufacturer’s device specifications - which are usually not available. For example, I wanted to connect to a blood pressure monitor via a Swift app, but the device required a sign-in process and the manufacturer refused to provide documentation - probably because their own app collected and stored user data on the company’s server. good luck and regards, Michaela
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Jul ’21
Reply to TabularData: DataFrame - parsing JSON array that is not at the root level
I decided to go with stripping the extraneous data, so created a String extension: extension String {     func midString(from: String, to: String) -> String {         guard let firstChar = firstIndex(of: "[") else { return "" }         guard let lastChar = lastIndex(of: "]") else { return ""}         return String(self[firstChar...lastChar])     } } get the JSON array with: let newJSON = jsonStr?.midString(from: "[", to: "]") This function is useful whenever there are header and footer surrounding a delimited array e.g. delimiters "{" and "}" NOTE: I use lastIndex(of: "]" ) in the hope that Swift is smart enough to scan from the end backwards towards the start of the array. Cheers, Michaela
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jul ’21
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:
Replies
Boosts
Views
Activity
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:
Replies
Boosts
Views
Activity
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:
Replies
Boosts
Views
Activity
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:
Replies
Boosts
Views
Activity
Aug ’21