Skip to content

Commit

Permalink
making things sendable for swift 6
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbarela committed Sep 18, 2024
1 parent 44b363b commit 69d0b98
Show file tree
Hide file tree
Showing 88 changed files with 531 additions and 351 deletions.
63 changes: 19 additions & 44 deletions Marlin/Marlin/CoreData/CoreDataDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,23 @@ import BackgroundTasks
import CoreData
import Combine

class CoreDataDataSource {
protocol CoreDataDataSource {
typealias Page = Int

var backgroundTask: UIBackgroundTaskIdentifier = .invalid
var cleanup: (() -> Void)?
var operation: CountingDataLoadOperation?

func registerBackgroundTask(name: String) {
NSLog("Register the background task \(name)")
backgroundTask = UIApplication.shared.beginBackgroundTask(withName: name) { [weak self] in
NSLog("iOS has signaled time has expired \(name)")
self?.cleanup?()
print("canceling \(name)")
self?.operation?.cancel()
print("calling endBackgroundTask \(name)")
self?.endBackgroundTaskIfActive()
}
}

func endBackgroundTaskIfActive() {
let isBackgroundTaskActive = backgroundTask != .invalid
if isBackgroundTaskActive {
NSLog("Background task ended. \(NSStringFromClass(type(of: self))) Load")
UIApplication.shared.endBackgroundTask(backgroundTask)
backgroundTask = .invalid
}
}

func publisher<T: NSManagedObject>(for managedObject: T,
in context: NSManagedObjectContext
) -> AnyPublisher<T, Never>
func executeOperationInBackground(operation: CountingDataLoadOperation) async -> Int
func buildPredicates(filters: [DataSourceFilterParameter]?) -> [NSPredicate]
func boundsPredicate(
minLatitude: Double,
maxLatitude: Double,
minLongitude: Double,
maxLongitude: Double
) -> NSPredicate
}

extension CoreDataDataSource {
func publisher<T: NSManagedObject>(for managedObject: T,
in context: NSManagedObjectContext
) -> AnyPublisher<T, Never> {
Expand All @@ -57,28 +46,14 @@ class CoreDataDataSource {
.eraseToAnyPublisher()
}

func executeOperationInBackground(task: BGTask? = nil) async -> Int {
if let task = task {
registerBackgroundTask(name: task.identifier)
guard backgroundTask != .invalid else { return 0 }
}

// Provide the background task with an expiration handler that cancels the operation.
task?.expirationHandler = {
self.operation?.cancel()
}

// Start the operation.
if let operation = operation {
MSI.shared.backgroundLoadQueue.addOperation(operation)
}
func executeOperationInBackground(operation: CountingDataLoadOperation) async -> Int {
MSI.shared.backgroundLoadQueue.addOperation(operation)

return await withCheckedContinuation { continuation in
// Inform the system that the background task is complete
// when the operation completes.
operation?.completionBlock = {
task?.setTaskCompleted(success: !(self.operation?.isCancelled ?? false))
continuation.resume(returning: self.operation?.count ?? 0)
operation.completionBlock = {
continuation.resume(returning: operation.count)
}
}
}
Expand Down
21 changes: 18 additions & 3 deletions Marlin/Marlin/Data/CountingDataLoadOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,27 @@
//

import Foundation
import BackgroundTasks
import UIKit

enum DataLoadOperationState: String {
case isReady
case isExecuting
case isFinished
}

class CountingDataLoadOperation: Operation {
// actor BackgroundOperationRunner {
// var operations: [UIBackgroundTaskIdentifier: Operation] = [:]
//
// func run(name: String) {
// var backgroundTask = UIApplication.shared.beginBackgroundTask(withName: name) { @Sendable [weak self] in
// operations.append(operation)
// operation.start()
// }
// }

// @MainActor
class CountingDataLoadOperation: Operation, @unchecked Sendable {
var count: Int = 0

var state: DataLoadOperationState = .isReady {
Expand Down Expand Up @@ -44,13 +57,15 @@ class CountingDataLoadOperation: Operation {
}
}

@MainActor func finishLoad() {
@MainActor
func finishLoad() {
self.state = .isFinished
}

func loadData() async {
fatalError("Load data should be implemented in sub class")
}

@MainActor func startLoad() { }
@MainActor
func startLoad() { }
}
2 changes: 1 addition & 1 deletion Marlin/Marlin/Data/DataFetchOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ enum DataFetchOperationState: String {
case isFinished
}

class DataFetchOperation<DataModel>: Operation {
class DataFetchOperation<DataModel>: Operation, @unchecked Sendable {

var data: [DataModel] = []

Expand Down
15 changes: 9 additions & 6 deletions Marlin/Marlin/DataSources/Bookmark/BookmarkModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
import Foundation
import CoreData

class BookmarkModel: NSObject {
var dataSource: String?
var id: String?
var notes: String?
var timestamp: Date?
var itemKey: String?
final class BookmarkModel: NSObject, Sendable {
let dataSource: String?
let id: String?
let notes: String?
let timestamp: Date?
let itemKey: String?
let uri: URL?

func isEqualTo(_ other: BookmarkModel) -> Bool {
guard let otherShape = other as? Self else { return false }
Expand All @@ -28,6 +29,7 @@ class BookmarkModel: NSObject {
}

init(bookmark: Bookmark) {
self.uri = bookmark.objectID.uriRepresentation()
self.dataSource = bookmark.dataSource
self.id = bookmark.id
self.itemKey = bookmark.itemKey
Expand All @@ -41,5 +43,6 @@ class BookmarkModel: NSObject {
self.notes = notes
self.timestamp = timestamp
self.itemKey = itemKey
self.uri = nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import CoreLocation
extension DGPSStationModel {
init(differentialGPSStation: DifferentialGPSStation) {
self.canBookmark = true
self.differentialGPSStation = differentialGPSStation
// self.differentialGPSStation = differentialGPSStation
self.aidType = differentialGPSStation.aidType
self.deleteFlag = differentialGPSStation.deleteFlag
self.featureNumber = Int(differentialGPSStation.featureNumber)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ struct DGPSStationModel:
try? container.encode(volumeNumber, forKey: .volumeNumber)
}

var differentialGPSStation: DifferentialGPSStation?
// var differentialGPSStation: DifferentialGPSStation?

var aidType: String?
var deleteFlag: String?
Expand Down
2 changes: 1 addition & 1 deletion Marlin/Marlin/DataSources/Light/FogSignalImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation
import UIKit

class FogSignalImage: UIImage {
class FogSignalImage: UIImage, @unchecked Sendable {

class func drawArcLines(
center: CGPoint,
Expand Down
2 changes: 1 addition & 1 deletion Marlin/Marlin/DataSources/Light/LightColorImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class LightImage: DataSourceImage {
}
}

class LightColorImage: UIImage {
class LightColorImage: UIImage, @unchecked Sendable {

convenience init?(
frame: CGRect,
Expand Down
8 changes: 5 additions & 3 deletions Marlin/Marlin/DataSources/Light/LightModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ struct LightModel: Locatable, Bookmarkable, Codable, CustomStringConvertible, Ha
return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}

var light: Light?
var uri: URL?
// var light: Light?

private enum CodingKeys: String, CodingKey {
case volumeNumber
Expand Down Expand Up @@ -198,7 +199,8 @@ struct LightModel: Locatable, Bookmarkable, Codable, CustomStringConvertible, Ha
}

init(light: Light) {
self.light = light
// self.light = light
self.uri = light.objectID.uriRepresentation()
self.canBookmark = true
self.aidType = light.aidType
self.characteristic = light.characteristic
Expand Down Expand Up @@ -412,7 +414,7 @@ struct LightModel: Locatable, Bookmarkable, Codable, CustomStringConvertible, Ha
}

func isEqualTo(_ other: LightModel) -> Bool {
return self.light == other.light
return self.uri == other.uri
}

static func == (lhs: LightModel, rhs: LightModel) -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion Marlin/Marlin/DataSources/Light/RaconImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation
import UIKit

class RaconImage: UIImage {
class RaconImage: UIImage, @unchecked Sendable {

convenience init?(
frame: CGRect,
Expand Down
2 changes: 1 addition & 1 deletion Marlin/Marlin/DataSources/Light/StructureImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ enum StructureType {
case unknown
}

class StructureImage: UIImage {
class StructureImage: UIImage, @unchecked Sendable {

static let unknownBouyColor = 0x5587978B

Expand Down
2 changes: 1 addition & 1 deletion Marlin/Marlin/DataSources/MODU/ModuModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ struct ModuModel: Locatable, Bookmarkable, Codable, GeoJSONExportable, CustomStr
var specialStatus: String?
var subregion: Int?

var bookmark: Bookmark?
var bookmark: BookmarkModel?

func isEqualTo(_ other: ModuModel) -> Bool {
return self.name == other.name
Expand Down
6 changes: 3 additions & 3 deletions Marlin/Marlin/DataSources/Port/PortModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct PortModel: Locatable, Bookmarkable, Codable, GeoJSONExportable, CustomStr
}
var canBookmark: Bool = false

var port: Port?
// var port: Port?

var alternateName: String?
var anchorageDepth: Int?
Expand Down Expand Up @@ -210,7 +210,7 @@ struct PortModel: Locatable, Bookmarkable, Codable, GeoJSONExportable, CustomStr
var globalId: String?

func isEqualTo(_ other: PortModel) -> Bool {
return self.port == other.port
return self.id == other.id
}

static func == (lhs: PortModel, rhs: PortModel) -> Bool {
Expand Down Expand Up @@ -534,7 +534,7 @@ struct PortModel: Locatable, Bookmarkable, Codable, GeoJSONExportable, CustomStr
// disable this data model has a lot of properties
// swiftlint:disable function_body_length
init(port: Port) {
self.port = port
// self.port = port
self.canBookmark = true
self.alternateName = port.alternateName
self.anchorageDepth = Int(port.anchorageDepth)
Expand Down
13 changes: 0 additions & 13 deletions Marlin/Marlin/DependencyInjection/DependencyInjection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@ public protocol InjectionKey {
static var currentValue: Self.Value { get set }
}

/**
private struct NetworkProviderKey: InjectionKey {
static var currentValue: NetworkProviding = NetworkProvider()
}

extension InjectedValues {
var networkProvider: NetworkProviding {
get { Self[NetworkProviderKey.self] }
set { Self[NetworkProviderKey.self] = newValue }
}
}
*/

// Provides access to injected dependencies.
struct InjectedValues {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extension Array where Element == DataSourceFilterParameter {
}
}

struct DataSourceFilterParameter: Identifiable, Hashable, Codable {
struct DataSourceFilterParameter: Identifiable, Hashable, Codable, Sendable {
static func == (lhs: DataSourceFilterParameter, rhs: DataSourceFilterParameter) -> Bool {
return lhs.id == rhs.id
}
Expand Down
53 changes: 39 additions & 14 deletions Marlin/Marlin/GeoPackage/GeoPackageExportViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,10 @@ class GeoPackageExportViewModel: ObservableObject {
countChangeCancellable = Publishers.CombineLatest3($dataSources, commonViewModel.$filters, publisher)
.receive(on: RunLoop.main)
.sink { [weak self] _ in
guard let self = self else { return }
self.updateCounts()
Task {
guard let self = self else { return }
await self.updateCounts()
}
}
}

Expand All @@ -130,26 +132,49 @@ class GeoPackageExportViewModel: ObservableObject {
}
}

func updateCounts() {
func updateCounts() async {
NSLog("Update Counts commonFilters are \(self.commonViewModel.filters)")
self.counts = dataSources.reduce(into: [DataSourceDefinitions: Int]()) {

if let definition = DataSourceDefinitions.from($1) {
var temp: [DataSourceDefinitions: Int] = [:]

for dataSource in dataSources {
if let definition = DataSourceDefinitions.from(dataSource) {
let filters = (self.filterViewModels[definition]?.filters ?? []) + self.commonViewModel.filters

switch definition {
case .route: $0[definition] = self.routeRepository?.getCount(filters: filters)
case .asam: $0[definition] = self.asamRepository.getCount(filters: filters)
case .modu: $0[definition] = self.moduRepository.getCount(filters: filters)
case .differentialGPSStation: $0[definition] = self.dgpsRepository.getCount(filters: filters)
case .port: $0[definition] = self.portRepository.getCount(filters: filters)
case .navWarning: $0[definition] = self.navigationalWarningRepository.getCount(filters: filters)
case .light: $0[definition] = self.lightRepository.getCount(filters: filters)
case .radioBeacon: $0[definition] = self.radioBeaconRepository.getCount(filters: filters)
case .route: temp[definition] = self.routeRepository?.getCount(filters: filters)
case .asam: temp[definition] = await self.asamRepository.getCount(filters: filters)
case .modu: temp[definition] = self.moduRepository.getCount(filters: filters)
case .differentialGPSStation: temp[definition] = self.dgpsRepository.getCount(filters: filters)
case .port: temp[definition] = self.portRepository.getCount(filters: filters)
case .navWarning: temp[definition] = self.navigationalWarningRepository.getCount(filters: filters)
case .light: temp[definition] = self.lightRepository.getCount(filters: filters)
case .radioBeacon: temp[definition] = self.radioBeaconRepository.getCount(filters: filters)
default: break
}
}
}

self.counts = temp

// self.counts = dataSources.reduce(into: [DataSourceDefinitions: Int]()) {
//
// if let definition = DataSourceDefinitions.from($1) {
// let filters = (self.filterViewModels[definition]?.filters ?? []) + self.commonViewModel.filters
//
// switch definition {
// case .route: temp[definition] = self.routeRepository?.getCount(filters: filters)
// case .asam: temp[definition] = await self.asamRepository.getCount(filters: filters)
// case .modu: temp[definition] = self.moduRepository.getCount(filters: filters)
// case .differentialGPSStation: temp[definition] = self.dgpsRepository.getCount(filters: filters)
// case .port: temp[definition] = self.portRepository.getCount(filters: filters)
// case .navWarning: temp[definition] = self.navigationalWarningRepository.getCount(filters: filters)
// case .light: temp[definition] = self.lightRepository.getCount(filters: filters)
// case .radioBeacon: temp[definition] = self.radioBeaconRepository.getCount(filters: filters)
// default: break
// }
// }
// return temp
// }
}

func toggleDataSource(definition: any DataSourceDefinition) {
Expand Down
Loading

0 comments on commit 69d0b98

Please sign in to comment.