crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

GameEntity+ContentKey.swift (1269B)


      1 import CoreData
      2 import Foundation
      3 
      4 extension GameEntity {
      5     /// Rewrites the App Group content-key directory from Core Data ground truth:
      6     /// one `gameID → contentKey` entry per shared game whose notification
      7     /// credentials carry a key. The Notification Service Extension reads it to
      8     /// decrypt the structured push payload (`PushPayloadCipher`) on a suspended
      9     /// device, where it can't reach Core Data. Called after a local mint
     10     /// (`GameStore.setNotification`), after sync adopts an inbound credential,
     11     /// and once at launch as a heal. Must run inside the context's queue
     12     /// (`performAndWait`) when `ctx` is a background context.
     13     static func rebuildContentKeyDirectory(in ctx: NSManagedObjectContext) {
     14         let req = NSFetchRequest<GameEntity>(entityName: "GameEntity")
     15         req.predicate = NSPredicate(format: "notification != nil")
     16         var directory: [String: String] = [:]
     17         for game in (try? ctx.fetch(req)) ?? [] {
     18             guard let id = game.id,
     19                   let key = GamePushCredentials.decode(game.notification)?.contentKey,
     20                   !key.isEmpty
     21             else { continue }
     22             directory[id.uuidString] = key
     23         }
     24         ContentKeyDirectory.save(directory)
     25     }
     26 }