I tested in Swift something similar, without crash on simulator 18.4
let string = "ffi"
var style = [NSAttributedString.Key.foregroundColor: UIColor.black, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17, weight: .regular), NSAttributedString.Key.paragraphStyle: NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle]
let attributeString = NSMutableAttributedString(string: string, attributes: style)
testField.attributedText = attributeString
Post
Replies
Boosts
Views
Activity
Welcome to the forum
MapMarker is deprecated and required extra parmateres in Map:
Deprecated: Use Marker along with Map initializers that take a MapContentBuilder instead.
Here is the example from Xcode doc:
struct IdentifiablePlace: Identifiable {
let id: UUID
let location: CLLocationCoordinate2D
init(id: UUID = UUID(), lat: Double, long: Double) {
self.id = id
self.location = CLLocationCoordinate2D(
latitude: lat,
longitude: long)
}
}
struct PinAnnotationMapView: View {
let place: IdentifiablePlace = IdentifiablePlace(lat: 0, long: 0)
@State var region: MKCoordinateRegion = MKCoordinateRegion()
var body: some View {
Map(coordinateRegion: $region, annotationItems: [place])
{ place in
MapMarker(coordinate: place.location)
}
}
}
I tested your code replacing MapMarker by Marker, it works (with a String as first parameter.
Map {
ForEach(markers) { marker in
Marker("test", coordinate: marker.coordinate) // MapMarker
}
}
To further test, I mimicked your JSON, considering it would look like this (each element with an id and a name). They are in fact Dictionaries:
[{"id":"First","name":"One"},
{"id":"Second","name":"Two"},
{"id":"Third","name":"Three"}]
If so, the test code (I commented out the url part to replace by hardwired data)
typealias MyDict = [String: String] // A dictionary is defined as [key:Value]
struct Item : Codable { // Need Codable to be used by Decoder
var id: String // Identical to the key:value of the JSON (you can later change the name using CodingKeys …
var name: String
}
// ----------- this part for hardwired test --------------
// This to create data by hand ; in your case, data will come from php request
let one = Item(id: "First", name:"One")
let two = Item(id: "Second", name:"Two")
let three = Item(id: "Third", name:"Three")
let itemData = [one, two, three] // Here, 3 elements in JSON
let data = try JSONEncoder().encode(itemData) // create the data that you'll in fact retrieve from url
print("JSON Data", String(data: testJSONData, encoding: .utf8)!) // To check what is in data
// -------------------------------------------------------
var quotes: [MyDict] { // back to array of Dict
var output: [MyDict] = []
// ----------- 3 lines commented for test with hardwired data --------------
// 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 were built with encode, but that would work with url if you uncomment those 3 lines
if let json = try? JSONDecoder().decode([MyDict].self, from: data) {
output = json
}
// }
// }
// }
return output
}
print("quotes", quotes)
You get this (once again, dictionaries are not ordered):
JSON Data [{"id":"First","name":"One"},{"id":"Second","name":"Two"},{"id":"Third","name":"Three"}]
quotes [["name": "One", "id": "First"], ["name": "Two", "id": "Second"], ["name": "Three", "id": "Third"]]
if json in server is like this:
[{"id":"First","name":"One"},
{"id":"Second","name":"Two"},
{"id":"Third","name":"Three"}]
Your own code should then be:
struct Item : Codable { // Need Codable to be used by Decoder
var id: String // Identical to the key:value of the JSON (you can later change the name using CodingKeys …
var 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([Item].self, from: data) {
output = json
}
}
}
}
return output
}
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
}
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)
I have selected iPhone simulator and Watch simulator that are paired. To no avail.
PS: in older days, we could select target as iPhone + Watch. That does not seem possible anymore ?
If that can help: https://discussions.unity.com/t/ios-app-crashes-seconds-after-opening-with-bug-type-309/922451
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
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.
Welcome to the forum.
Your post does not provide enough information for anyone to help.
What is Xcord ?
Read here to know how to properly use the forum: https://developer.apple.com/forums/thread/706527
Which hours are ignored in the first case ? They all seem visible (except 24, but 24 is also 0…)
datemin and datermax seem to apply more appropriate for xAxis than yAxis.
Did you try:
Chart(...) { ... }
.chartYScale(domain: [0, 24])
Welcome to the forum.
Please note that the forum is not the channel to (try to) speak to reviewers. The appeal tou did is the right way.
When you post screenshots, please reduce their size. They are insanely large.
It seems over for a few hours (now 1 pm PST).
Did you mention it in the comments to reviewer that the app was created 13 years ago ?
However, take care that some recent features may not be considered as spam.
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 {