Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Graniteman
Nov 16, 2002

SaTaMaS posted:

Some sample code would be awesome, but monitoring for changes is key, in Core Data I can listen for the ContextDidSaveNotification, copy the changes from the viewContext to the syncContext, then look at the objects associated with the notification, and for each endpoint I have there is an associated NSPredicate that when true means the object needs to be synchronized. For SwiftData I know there is a new query language but I'm not sure how to run queries on the set of changed objects from a save notification like I can in Core Data.

As far as I can tell there is no mechanism like getting ContextDidSaveNotification and being able to filter a list of transactions. It's a really big problem! It means I don't see a way to do deduplication when you sync between devices. With Core Data if I created a duplicate entry on a second device synced by CloudKit I could monitor the incoming transactions and deduplicate. Apple has a whole support article on the topic. With SwiftData if you sync between devices with CloudKit I don't see any way to do it. The hobby project I'm working on now uses SwiftData but I've got CloudKit sync turned off until that problem is solved. It's aggravating because getting free cross device sync without a login is a big part of the value proposition of using Apple's first-party SDKs. If you find a way to handle this please message me or post here because god drat...

Anyway, to use ModelActor classes for background work with SwiftData you need to create a class like this:
code:
final actor MyFancyModelActor: ModelActor {
    // MARK: - ModelActor conformance requirements
    nonisolated let modelContainer: ModelContainer
    nonisolated let modelExecutor: any ModelExecutor

    // You need to pass in the same ModelContainer definition you use throughout the rest of your app. I keep a PersistenceController.shared.container for this purpose.
    init(modelContainer: ModelContainer) {
        self.modelContainer = modelContainer
        let modelContext = ModelContext(modelContainer)
        self.modelExecutor = DefaultSerialModelExecutor(modelContext: modelContext)
    }
    
    // MARK: - Your custom code for the class
    func doAThing(toObjectWithID objectID: PersistentIdentifier) {
        // ModelActors have this subscript defined where you can get an object from its context
        guard let theObjectIWant: MyModelObjectType = self[objectID, as: MyModelObjectType.self] else { return }

        // ModelActors have a protocol-provided self.modelContext which runs isolated to the thread / actor. You can freely use it within ModelActor functions.
        if self.modelContext.hasChanges {
            // do something
        }
    }
}
The call site works like this
code:
let myModelActor = MyFancyModelActor(modelContainer: PersistenceController.shared.container)
Task {
    await myModelActor.doAThing(toObjectWithID: blahblahblah)
}
You can use this setup to freely do work on any thread you want without getting crashes. SwiftData is less sensitive to thread problems than Core Data, but it still won't let you pass ModelObjects across threads without crashes.

Graniteman fucked around with this message at 17:42 on Oct 18, 2023

Adbot
ADBOT LOVES YOU

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Does the newer (but still years old) Core Data external changes notification get posted by SwiftData? NSPersistentStoreRemoteChange I think.

Also I don't think there's any need to make your MyFancyModelActor method async in that example. It's already asynchronous with respect to other actors.

Graniteman
Nov 16, 2002

It's an optional flag to enable NSPersistentStoreRemoteChangeNotificationPostOptionKey with Core Data, and I haven't checked to see if they set that flag. The problem is that to merge changes or generally handle the contents of that change notification, you have to query the core data context for transaction history (as NSPersistentHistoryResult), which you can parse to get NSManagedObjectID (the Core Data identifier), which you can ultimately use to get a list of all of the Core Data NSManagedObjects that were changed in that notification. If you are using a SwiftData project, you don't have an easy way to convert those NSManagedObjects to SwiftData ModelObjects. Which points back to my whining that they suggest you reimplement your persistence stack in Core Data if you want to do that anything they haven't implemented. If you do implement a Core Data stack, then you can convert your transaction history into Core Data objects, which you can then convert to Swift Data objects. Or just operate directly on the Core Data objects, which of course I would just do that and not use Swift Data at all in the app if it was critical to process transactions.

I may be missing something here, but I don't see a way to parse transaction history like you can with Core Data. With Core Data your context can request a NSPersistentHistoryTransaction.fetchRequest, which doesn't seem to exist for SwiftData. I'm genuinely no expert in Core Data or Swift Data, but I've shipped a couple of indie apps using Core Data with this cloudkit de-dupe stuff, and am working on a Swift Data app where I haven't found a work around. Apple's docs suck, and there hasn't been enough time for StackOverflow to solve all of my problems yet.

And yeah you are right that the actor method doesn't need to be async. I'll edit that post's code.

Graniteman fucked around with this message at 17:45 on Oct 18, 2023

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
I think you just saved future-me a few hours of frustration so thank you for writing that out. Wish I had any other ideas :(

Graniteman
Nov 16, 2002

pokeyman posted:

I think you just saved future-me a few hours of frustration so thank you for writing that out. Wish I had any other ideas :(

Sure I’m happy to help. If you want any more example code for any of that Core Data stuff I’m happy to put up gists or whatever.

For Swift Data I feel like we are just in that early framework period where they just haven’t implemented everything yet. Apple devs continue to say that duplicate Feedbacks count as votes internally when they allocate resources so please submit feedbacks that ask for the missing features you need the most.

duck monster
Dec 15, 2004

Vesi posted:

I use flutter for iOS stuff now even if we don't always need android, xcode is there just for setting up the devices and ipa upload

How are you finding flutter? I grabbed one of those Udemy courses, but the instructors english is so poor and shouty its extremely hard to follow. The ios dev at work uses it and it *looks* like a decent system (I was rather impressed at some system he had in there that could straight up execute gherkin behavior specs as tests) but before investing too hard in learning it I really need to figure out if its a smart path to go down.

Vesi
Jan 12, 2005

pikachu looking at?

duck monster posted:

How are you finding flutter? I grabbed one of those Udemy courses, but the instructors english is so poor and shouty its extremely hard to follow. The ios dev at work uses it and it *looks* like a decent system (I was rather impressed at some system he had in there that could straight up execute gherkin behavior specs as tests) but before investing too hard in learning it I really need to figure out if its a smart path to go down.

I've been using it for 5 years with multiple projects and no complaints, it's my favourite way of doing UI code now, pixel-perfect 120fps performance too unlike other cross-platform kits, and there's 3rd party plugins for almost everything platform-specific, google seems committed to supporting it too

the iOS styled widgets are google-made imitations of the actual iOS widgets which can throw off some purists and I'm not sure if desktop and web are production ready yet, but with mobile I can develop on android and be 100% certain it'll work the same way on iOS

duck monster
Dec 15, 2004

Vesi posted:

I've been using it for 5 years with multiple projects and no complaints, it's my favourite way of doing UI code now, pixel-perfect 120fps performance too unlike other cross-platform kits, and there's 3rd party plugins for almost everything platform-specific, google seems committed to supporting it too

the iOS styled widgets are google-made imitations of the actual iOS widgets which can throw off some purists and I'm not sure if desktop and web are production ready yet, but with mobile I can develop on android and be 100% certain it'll work the same way on iOS

I couldnt imagine wanting to use it for web (Svelete supremacy! But Vue and react if I absolutely, dragged against my will *must*.), but the desktop thing is intriguing to me. I loving hate wrapped website "apps" on the desktop.

Small White Dragon
Nov 23, 2007

No relation.
Seems like every time I hook up my iOS device to test, the "trust this computer?" prompt re-appears. Is there no a longer way to tell it to always trust this same computer?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Small White Dragon posted:

Seems like every time I hook up my iOS device to test, the "trust this computer?" prompt re-appears. Is there no a longer way to tell it to always trust this same computer?

My ipad asked me twice today and I was pretty sure I had trusted it before. And after the second time I failed to notice it wasn’t charging, so it just blinked out after a few hours. Not sure what’s up but you’re not alone.

go play outside Skyler
Nov 7, 2005


It pops up again after every system update, including minor ones. It also seems to happen when your phone has been "force locked" and requires your password instead of Face ID.

But as always with Apple this stuff is not documented anywhere and is anyone's guess.

SaTaMaS
Apr 18, 2003
I have an .overlay that appears when a @FetchRequest isn't nil. It works great but is there any way to animate the overlay appearing/disappearing without using withAnimation or a redundant @State var showOverlay? Just applying .animation and .transition using fetchRequest.first as the value doesn't seem to do anything.

SaTaMaS fucked around with this message at 22:14 on Dec 22, 2023

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
I have no useful experience but from reading the docs I know FetchRequest has initializers that take an Animation or a Transition, do those do anything helpful?

SaTaMaS
Apr 18, 2003

pokeyman posted:

I have no useful experience but from reading the docs I know FetchRequest has initializers that take an Animation or a Transition, do those do anything helpful?

Those are related to animating in and out the rows produced by the FetchRequest

SaTaMaS
Apr 18, 2003
It looks like the best approach is @State var item: FetchRequestItem? (.animation would also work but still requires the @State var)
code:
.onChange(of: fetchRequest.first) { newValue in
   withAnimation {
      self.item = newValue
   }
}

Fate Accomplice
Nov 30, 2006




anyone have experience using Pointfree's Swift Composable Architecture?

some teams around me are implementing it and I'm investigating what that'll mean for my codebase.

101
Oct 15, 2012


Vault Dweller

Fate Accomplice posted:

anyone have experience using Pointfree's Swift Composable Architecture?

some teams around me are implementing it and I'm investigating what that'll mean for my codebase.

Yes. I have encouraged and assisted in moving both our teams iOS and macOS codebases over to it in the last year. I think it’s fantastic and has an excellent ecosystem of other niceties around it too (dependencies, navigation etc)

Glimm
Jul 27, 2005

Time is only gonna pass you by

Do the Swift/C++ interop updates change anything with C? Is it possible to make a C target in an SPM project depend on a Swift target?

If not, would the best roundabout way of doing this be to "convert" the project to Objective-C (rename files to .m) and import Swift code that way?

The long-term goal is to rewrite an old C project with ~190,000 LOC in Swift, replacing small bits as we go. The project is deployed on Linux.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
The great thing about Swift/C++ interop is that a ton of Swift APIs can be exposed to C++ automatically and for free: the C++ header directly declares the public ABI of the Swift module, then wraps as much of it as currently possible in idiomatic C++. That approach doesn’t work for C or ObjC because of the limitations of those languages: APIs have to fit into what the languages can express, and it has to be opt-in because the compiler has to generate new symbols for the C/ObjC compiler to call. Exporting to ObjC at least has a little bit of power because the ObjC object model is mostly compatible with Swift, but exporting to C would be so limited. It’s something we’ve talked about a little, but it’s hard to build momentum behind doing work there.

Instead of “converting” to ObjC, I’d suggest incrementally converting a few files to C++. That will require some headers to use extern “C” properly, but that’s probably a lot less work (and very mechanical) than trying to force everything through an ObjC-style API if it doesn’t look like that now.

Glimm
Jul 27, 2005

Time is only gonna pass you by

I naively attempted to build the project with a C++ compiler and got a lot of build errors :negative:

I'll look into that approach more - I was hoping ObjC would be a good idea since I have a lot more experience with it (C++ I haven't used since a single university course).

Thanks!

edit:

Building with C++ wasn't too bad, now to integrate it with my Swift code using SPM

Glimm fucked around with this message at 19:17 on Jan 15, 2024

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

Glimm posted:

Do the Swift/C++ interop updates change anything with C? Is it possible to make a C target in an SPM project depend on a Swift target?

I mean for this specifically you can certainly use the old @_cdecl annotation and then offer a standard MyCoolInterop.h header that declares the Swift function you want to all into... I've done this several times over the years to quickly get like enum functions and other loose items available for ObjC consumers of libraries.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Where on earth did pkl come from?

Adbot
ADBOT LOVES YOU

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Apparently Apple's been using it internally for years and just decided to open source it.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply