crossmate

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

ImportService.swift (1202B)


      1 import Foundation
      2 
      3 @MainActor
      4 final class ImportService {
      5     private let store: GameStore
      6     private let driveMonitor: DriveMonitor
      7 
      8     init(store: GameStore, driveMonitor: DriveMonitor) {
      9         self.store = store
     10         self.driveMonitor = driveMonitor
     11     }
     12 
     13     func importGame(from url: URL) -> UUID? {
     14         guard ["xd", "puz"].contains(url.pathExtension.lowercased()) else { return nil }
     15 
     16         let needsAccess = url.startAccessingSecurityScopedResource()
     17         defer {
     18             if needsAccess {
     19                 url.stopAccessingSecurityScopedResource()
     20             }
     21         }
     22 
     23         // Streaming capped read: bounds the bytes pulled into memory even
     24         // when the provider reports no file size (a `fileSizeKey` preflight
     25         // alone would fall through to an unbounded read in that case).
     26         guard let source = try? PuzzleFileReader.readSource(at: url) else {
     27             return nil
     28         }
     29 
     30         if driveMonitor.containerAvailable {
     31             try? driveMonitor.importFile(from: url)
     32         }
     33 
     34         if let existing = store.findGameID(matching: source) {
     35             return existing
     36         }
     37         return try? store.createGame(from: source)
     38     }
     39 }