Post

Replies

Boosts

Views

Activity

Reply to How to integrate data from a web service into an array
OK, quotes is no more an array of dict but an array of t-uples. Is it on purpose ? Look at your code. quotes is a computed property for which you have defined only a get and no set (see Swift doc to understand precisely). So you cannot modify it. you have not defined output. what is the decode type ? Do you want a dictionary ? But that's not how quotes is declared. Same confusion as before [[String:String]] You should refactor your code and put the url related code inside the quotes declaration. Try this (I have not set up the php so I cannot fully test) and tell if it works: var quotes: [(id: String, name: String)] { var output: [(id: String, name: String)] = [] if let url = URL(string:"https://www.TEST.com/test_connection.php") { URLSession.shared.dataTask(with: url) { (data, response, error) in if let data = data { if let json = try? JSONDecoder().decode([[String:String]].self, from: data){ json.forEach { row in var item: (id: String, name: String) = ("test id value", "test name value") output.append(item) } } } } } return output } Note that with recent versions of Swift, you don't need anymore to write if let data = data if it is the same name, but simply if let data { There is something curious in your code. You append the same item for all rows in the json. It should probably be something like (I'm guessing about your Json, it would help if you showed it): let item: (id: String, name: String) = (id: row.id, name: row.name) // ("test id value", "test name value") - no need for var, let is enough PS: it is a good practice here to define a type alias: So code would look like: typealias Item = (id: String, name: String) var quotes: [Item] { var output: [Item] = [] if let url = URL(string:"https://www.TEST.com/test_connection.php") { URLSession.shared.dataTask(with: url) { (data, response, error) in if let data { if let json = try? JSONDecoder().decode([[String:String]].self, from: data){ // if json.forEach { row in let item: Item = (id: row.id, name: row.name) // ("test id value", "test name value") output.append(item) } } } } } return output } If effectively the JSON is an array of Dict, you should more have something like; typealias MyDict = [String: String] // A dictionary is defined as [key:Value] var quotes: [MyDict] { var output: [MyDict] = [] if let url = URL(string:"https://www.TEST.com/test_connection.php") { URLSession.shared.dataTask(with: url) { (data, response, error) in if let data { // if let json = try? JSONDecoder().decode([MyDict].self, from: data){ output = json // That's the beauty of decoder to convert directly in the right structure [MyDict] } } } } return output }
Mar ’25
Reply to How to create an array using a loop
I just see I removed a linefeed in the code when pasting code, making allQuotes.append(newOutput) appear on the same line, which would then be in the comment, hence not executed ! Also : var not needed for newOutput ; let newOutput will do the job. Here is the properly formatted code. typealias MyDict = [String: String] // A dictionary is defined as [key:Value] var quotes: [MyDict] { var allQuotes = [MyDict]() // Creates an empty array for i in 1...4 { let newOutput = ["testID" : "testName \(i)", "secondID" : "secondName \(i)"] // a dict with 2 pairs allQuotes.append(newOutput) // We append the new output to the array of Dicts // <<-- on its own line } return allQuotes } print(quotes)
Mar ’25
Reply to How to create an array using a loop
There were several mistakes: [(id: String, name: String)] This is not a good definition of a dictionary, which is just [key:value], no labels var output = [id: "testID", name: "testName"] It does not make sense. If you wrote var output = ["id": "testID", "name": "testName"] that would be a dictionary with 2 elements, but that's not what you need here In your loop, you replace output at each iteration. So at the end you get only the 4th input. for i in 1...4 { var output = [id: "testID", name: "testName"] } Here is a correct code. I created a type alias for better readability. typealias MyDict = [String: String] // A dictionary is defined as [key:Value] var quotes: [MyDict] { var allQuotes = [MyDict]() // Creates an empty array for i in 1...4 { var newOutput = ["testID" : "testName \(i)", "secondID" : "secondName \(i)"] // a dict with 2 pairs allQuotes.append(newOutput) // We append the new output to the array of Dicts } return allQuotes } print(quotes) And you get the expected array: [["secondID": "secondName 1", "testID": "testName 1"], ["testID": "testName 2", "secondID": "secondName 2"], ["testID": "testName 3", "secondID": "secondName 3"], ["secondID": "secondName 4", "testID": "testName 4"]] Note that as always in dictionaries, the order of pairs is never guaranteed If you ask for an item: print(quotes[0]["testID"]) you get an optional (as the value for the key is nil if there is no value) Optional("testName 1") So you should write: print(quotes[0]["testID"] ?? "not found") and get: testName 1
Mar ’25
Reply to Why is this causing my app to crash?
You did not give enough information on the crash. What message ? Where exactly ? Your code is not complete to be tested: roomOrBlank missing I completed with: func roomOrBlank(course: Course) -> String { if course.room == "None" { return "" } else { return course.room } } currentCourse missing Rose, Lemon, White… missing: why not pass directly a Color as parameter instead of String ? So I tested by removing those lines and it does not crash. struct courseListView: View { var localcourse: Course var localtime: String func roomOrBlank(course: Course) -> String { if course.room == "None" { return "" } else { return course.room } } var body: some View { HStack{ Image(systemName: localcourse.listIcon) .foregroundColor(Color(localcourse.colour)) .padding(.leading, 5) Text(localcourse.name) .bold() Spacer() Text(localtime) Text(roomOrBlank(course: localcourse)).bold().padding(.trailing, 5) } .padding(.bottom, 1) // .background(currentCourse.name==localcourse.name ? Color(localcourse.colour).colorInvert(): nil) } } It does not seem the crash comes from removed line, as I tested with: .background(false ? Color(localcourse.colour).colorInvert(): nil) without causing a crash Anyway, you marked your own answer as correct. As it is not really an answer, we understand you closed the thread and don't need any more help.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’25
Reply to Settings.bundle
Did you register UserDefaults: UserDefaults.standard.register(defaults: defaults) // connect to Root.pList This is usually done in func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Feb ’25
Reply to Launching A New Build
The change itself is very simple and rapid: archive a new build (even with no change at all in code), just change version and build numbers in Appstore Connect, reorder the screenshots. If no new screenshot needed, it should take about 5 minutes for each localization submit the new version. After this there is no more work, unless the submission is rejected. So, the raw time is very limited, less than 1 hour. But, as @endecotp pointed out, the real workload may depend on extra tasks like testing, documenting, updating web pages for the app…  Only you can know.
Feb ’25
Reply to How to integrate data from a web service into an array
OK, quotes is no more an array of dict but an array of t-uples. Is it on purpose ? Look at your code. quotes is a computed property for which you have defined only a get and no set (see Swift doc to understand precisely). So you cannot modify it. you have not defined output. what is the decode type ? Do you want a dictionary ? But that's not how quotes is declared. Same confusion as before [[String:String]] You should refactor your code and put the url related code inside the quotes declaration. Try this (I have not set up the php so I cannot fully test) and tell if it works: var quotes: [(id: String, name: String)] { var output: [(id: String, name: String)] = [] if let url = URL(string:"https://www.TEST.com/test_connection.php") { URLSession.shared.dataTask(with: url) { (data, response, error) in if let data = data { if let json = try? JSONDecoder().decode([[String:String]].self, from: data){ json.forEach { row in var item: (id: String, name: String) = ("test id value", "test name value") output.append(item) } } } } } return output } Note that with recent versions of Swift, you don't need anymore to write if let data = data if it is the same name, but simply if let data { There is something curious in your code. You append the same item for all rows in the json. It should probably be something like (I'm guessing about your Json, it would help if you showed it): let item: (id: String, name: String) = (id: row.id, name: row.name) // ("test id value", "test name value") - no need for var, let is enough PS: it is a good practice here to define a type alias: So code would look like: typealias Item = (id: String, name: String) var quotes: [Item] { var output: [Item] = [] if let url = URL(string:"https://www.TEST.com/test_connection.php") { URLSession.shared.dataTask(with: url) { (data, response, error) in if let data { if let json = try? JSONDecoder().decode([[String:String]].self, from: data){ // if json.forEach { row in let item: Item = (id: row.id, name: row.name) // ("test id value", "test name value") output.append(item) } } } } } return output } If effectively the JSON is an array of Dict, you should more have something like; typealias MyDict = [String: String] // A dictionary is defined as [key:Value] var quotes: [MyDict] { var output: [MyDict] = [] if let url = URL(string:"https://www.TEST.com/test_connection.php") { URLSession.shared.dataTask(with: url) { (data, response, error) in if let data { // if let json = try? JSONDecoder().decode([MyDict].self, from: data){ output = json // That's the beauty of decoder to convert directly in the right structure [MyDict] } } } } return output }
Replies
Boosts
Views
Activity
Mar ’25
Reply to How to create an array using a loop
I just see I removed a linefeed in the code when pasting code, making allQuotes.append(newOutput) appear on the same line, which would then be in the comment, hence not executed ! Also : var not needed for newOutput ; let newOutput will do the job. Here is the properly formatted code. typealias MyDict = [String: String] // A dictionary is defined as [key:Value] var quotes: [MyDict] { var allQuotes = [MyDict]() // Creates an empty array for i in 1...4 { let newOutput = ["testID" : "testName \(i)", "secondID" : "secondName \(i)"] // a dict with 2 pairs allQuotes.append(newOutput) // We append the new output to the array of Dicts // <<-- on its own line } return allQuotes } print(quotes)
Replies
Boosts
Views
Activity
Mar ’25
Reply to How to create an array using a loop
There were several mistakes: [(id: String, name: String)] This is not a good definition of a dictionary, which is just [key:value], no labels var output = [id: "testID", name: "testName"] It does not make sense. If you wrote var output = ["id": "testID", "name": "testName"] that would be a dictionary with 2 elements, but that's not what you need here In your loop, you replace output at each iteration. So at the end you get only the 4th input. for i in 1...4 { var output = [id: "testID", name: "testName"] } Here is a correct code. I created a type alias for better readability. typealias MyDict = [String: String] // A dictionary is defined as [key:Value] var quotes: [MyDict] { var allQuotes = [MyDict]() // Creates an empty array for i in 1...4 { var newOutput = ["testID" : "testName \(i)", "secondID" : "secondName \(i)"] // a dict with 2 pairs allQuotes.append(newOutput) // We append the new output to the array of Dicts } return allQuotes } print(quotes) And you get the expected array: [["secondID": "secondName 1", "testID": "testName 1"], ["testID": "testName 2", "secondID": "secondName 2"], ["testID": "testName 3", "secondID": "secondName 3"], ["secondID": "secondName 4", "testID": "testName 4"]] Note that as always in dictionaries, the order of pairs is never guaranteed If you ask for an item: print(quotes[0]["testID"]) you get an optional (as the value for the key is nil if there is no value) Optional("testName 1") So you should write: print(quotes[0]["testID"] ?? "not found") and get: testName 1
Replies
Boosts
Views
Activity
Mar ’25
Reply to Why is this causing my app to crash?
You did not give enough information on the crash. What message ? Where exactly ? Your code is not complete to be tested: roomOrBlank missing I completed with: func roomOrBlank(course: Course) -> String { if course.room == "None" { return "" } else { return course.room } } currentCourse missing Rose, Lemon, White… missing: why not pass directly a Color as parameter instead of String ? So I tested by removing those lines and it does not crash. struct courseListView: View { var localcourse: Course var localtime: String func roomOrBlank(course: Course) -> String { if course.room == "None" { return "" } else { return course.room } } var body: some View { HStack{ Image(systemName: localcourse.listIcon) .foregroundColor(Color(localcourse.colour)) .padding(.leading, 5) Text(localcourse.name) .bold() Spacer() Text(localtime) Text(roomOrBlank(course: localcourse)).bold().padding(.trailing, 5) } .padding(.bottom, 1) // .background(currentCourse.name==localcourse.name ? Color(localcourse.colour).colorInvert(): nil) } } It does not seem the crash comes from removed line, as I tested with: .background(false ? Color(localcourse.colour).colorInvert(): nil) without causing a crash Anyway, you marked your own answer as correct. As it is not really an answer, we understand you closed the thread and don't need any more help.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Mar ’25
Reply to Settings.bundle
Did you register UserDefaults: UserDefaults.standard.register(defaults: defaults) // connect to Root.pList This is usually done in func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Replies
Boosts
Views
Activity
Feb ’25
Reply to Launching A New Build
The change itself is very simple and rapid: archive a new build (even with no change at all in code), just change version and build numbers in Appstore Connect, reorder the screenshots. If no new screenshot needed, it should take about 5 minutes for each localization submit the new version. After this there is no more work, unless the submission is rejected. So, the raw time is very limited, less than 1 hour. But, as @endecotp pointed out, the real workload may depend on extra tasks like testing, documenting, updating web pages for the app…  Only you can know.
Replies
Boosts
Views
Activity
Feb ’25
Reply to How to know if a user has received a notification?
Did you look at this (notificatiosns with actions): https://developer.apple.com/documentation/usernotifications/handling-notifications-and-notification-related-actions You would know if user has tapped a button (AFAIU, not if he simply discarder the notification or did not see it)
Topic: Safari & Web SubTopic: General Tags:
Replies
Boosts
Views
Activity
Feb ’25