I created an example project. Please see FB13192619
Post
Replies
Boosts
Views
Activity
Oh wow! That's indeed interesting.
I just added some rounding when creating the CLLocationCoordinate2Dobject and it now works fine.
let _lat = (lat * 1_000_000).rounded() / 1_000_000
let _lon = (lon * 1_000_000).rounded() / 1_000_000
CLLocationCoordinate2D(latitude: _lat, longitude: _lon)
Thank you for your help. I will mark your answer as the accepted one, because it works as a workaround.
I also created a feedback: FB10812168 and mentioned this thread in it
I also created a Feedback: FB9971630
iPhone language set to french has the same problem.
Also with the latest Xcode release
Just tried it with
Xcode: Version 13.3 (13E113)
Simulator: Version 13.3 (977.2)
SimulatorKit 618
CoreSimulator 802.6
I see now what I did wrong. I need to JSON encode the wrapper struct which holds the attributed string, so this can then use my custom attributes.
Here is my complete example. Maybe it also helps someone else:
import SwiftUI
extension AttributeScopes {
var myApp: MyAppAttributes.Type { MyAppAttributes.self }
struct MyAppAttributes: AttributeScope {
let alternativeGreeting: AlternativeGreetingTextAttribute
let swiftUI: SwiftUIAttributes
}
}
extension AttributeDynamicLookup {
subscript<T: AttributedStringKey>(dynamicMember keyPath: KeyPath<AttributeScopes.MyAppAttributes, T>) -> T { self[T.self] }
}
extension AttributeScopes.MyAppAttributes {
enum AlternativeGreetingTextAttribute: CodableAttributedStringKey {
typealias Value = String
static let name = "alternativeGreeting"
}
}
// Wrapper struct to also encode custom attributes
struct CodableType: Codable {
@CodableConfiguration(from: \.myApp)
var attrStr = AttributedString()
}
var attStr = AttributedString("Hello Max.")
attStr[attStr.range(of: "Hello")!].alternativeGreeting = "Hi"
attStr[attStr.range(of: "Max")!].personNameComponent = .givenName
// Decode to JSON, but use wrapper struct to recognize custom attributes
let jsonData = try JSONEncoder().encode(CodableType(attrStr: attStr))
print(String(data: jsonData, encoding: .utf8) ?? "no data")
print("-------")
// From JSON back to AttributedString
print(try JSONDecoder().decode(CodableType.self, from: jsonData).attrStr)
Thanks for the fast answer, but I think I'm still missing something.
I now created my own struct like this:
struct MyModel: Codable, Hashable {
@CodableConfiguration(from: \.myApp) var attrStr: AttributedString = AttributedString()
}
And continued with:
enum MyModelTextAttribute: CodableAttributedStringKey {
typealias Value = MyModel
static let name = "myModelTextAttribute"
}
extension AttributeScopes {
struct MyAppAttributes: AttributeScope {
let myModelTextAttribute: MyModelTextAttribute
let swiftUI: SwiftUIAttributes
}
var myApp: MyAppAttributes.Type { MyAppAttributes.self }
}
extension AttributeDynamicLookup {
subscript<T: AttributedStringKey>(dynamicMember keyPath: KeyPath<AttributeScopes.MyAppAttributes, T>) -> T { self[T.self] }
}
The JSON decoding of the model works fine:
let model = MyModel(attrStr: AttributedString("Hi"))
let json = try JSONEncoder().encode(model)
print(String(data: json, encoding: .utf8) ?? "no data")
// prints: {"attrStr":"Hi"}
So I created an attributed string and set the attributes:
var attStr = AttributedString("Hello, here is some text.")
let range1 = attStr.range(of: "Hello")!
let range2 = attStr.range(of: "text")!
attStr[range1].myModelTextAttribute = model
attStr[range2].foregroundColor = .blue
Printing the attributed string with print(attStr) looks also fine:
Hello {
myModelTextAttribute = MyModel(_attrStr: Foundation.CodableConfiguration<Foundation.AttributedString, (extension in __lldb_expr_87):Foundation.AttributeScopes.MyAppAttributes>(wrappedValue: Hi {
}))
}
, here is some {
}
text {
SwiftUI.ForegroundColor = blue
}
. {
}
But if I now try to convert it to JSON, my custom attribute is missing:
let jsonData = try JSONEncoder().encode(attStr)
print(String(data: jsonData, encoding: .utf8) ?? "no data")
// prints: ["Hello",{},", here is some ",{},"text",{"SwiftUI.ForegroundColor":{}},".",{}]
I also tried option 2 with a custom encode function in MyModel instead, but got the same result. Here is also my implementation for that:
struct MyModel: Codable, Hashable {
var attrStr: AttributedString = AttributedString()
enum MyCodingKey: CodingKey {
case attrStrKey
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: MyCodingKey.self)
try container.encode(attrStr, forKey: .attrStrKey, configuration: AttributeScopes.MyAppAttributes.self)
}
}
Filed a feedback:
FB9810895: Swim stroke style not displayed in workout summary in Fitness app
Hi.
Thank you!
Here are the feedbacks I created:
FB9810882: Location metakeys for indoor swim workouts
FB9810895: Swim stroke style not displayed in workout summary in Fitness app
FB9810889: Extend HKSwimmingStrokeStyle
There are multiple options to save data persistent on the device.
user settings
write to files
database
core data with different underlaying storing options
documents
etc.
It all depends on the data you want to save and the amount of data.
If there will be thousands of records you probably want to use a database or core data.
Loading some objects from a local JSON file for initialisation sounds fine to me.An entity with its attributes, relationships etc. describes your object. It is defined in your app and should be there.It sounds like you rather want to check if there are already saved objects.You can simply check if there are any saved objects in your store and only add your example objects if the store is empty.Or, assuming there is some kind of identifier which makes your object unique, you can set the constraints of your entity to this attribute.You should also set a merge policy then to specify the required behaviour when another object with the same identifier shows up.
You could also do plain insert or batch insert on your own to reduce your memory footprint.Depends on your amount of data though.Check out https://developer.apple.com/documentation/coredata/loading_and_displaying_a_large_data_feed
"All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull"See: https://developer.apple.com/documentation/foundation/jsonserializationLooks to me like you have 2 options:1) replace your key="created" dictionary items explicit to [String : Date] instead of [String : Any]2) save the created as a number in the database and create a computed property which will transform that number to a date object
What does your NSBatchInsertRequest call look like when you try to insert your data?NSBatchInsertRequest needs for the objects parameter [[String : Any]]Looks like the value type for your created attribute is not a Date.
I have the same problem
I have the same problem