Switching core target and tests to Swift 6

This commit is contained in:
Selim Mustafaev 2025-04-11 17:55:48 +03:00
parent dc6281ac46
commit 586261fedd
12 changed files with 58 additions and 33 deletions

View File

@ -1891,7 +1891,7 @@
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES; SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
@ -1916,7 +1916,7 @@
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES; SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; name = Release;
@ -1943,7 +1943,7 @@
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES; SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AutoCat.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/AutoCat"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AutoCat.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/AutoCat";
}; };
@ -1970,7 +1970,7 @@
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES; SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AutoCat.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/AutoCat"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AutoCat.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/AutoCat";
}; };
@ -2001,7 +2001,7 @@
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG MOCKING"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG MOCKING";
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES; SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = ""; VERSION_INFO_PREFIX = "";
@ -2032,7 +2032,7 @@
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES; SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = ""; VERSION_INFO_PREFIX = "";

View File

@ -2,7 +2,7 @@ import Foundation
public actor ApiService: ApiServiceProtocol { public actor ApiService: ApiServiceProtocol {
var settingsService: SettingsServiceProtocol let settingsService: SettingsServiceProtocol
public init(settingsService: SettingsServiceProtocol) { public init(settingsService: SettingsServiceProtocol) {

View File

@ -9,6 +9,7 @@
import CoreLocation import CoreLocation
import Mockable import Mockable
@MainActor
@Mockable @Mockable
public protocol GeocoderProtocol { public protocol GeocoderProtocol {

View File

@ -55,7 +55,7 @@ public final class LocationService {
return VehicleEventDto( return VehicleEventDto(
lat: coordinate.latitude, lat: coordinate.latitude,
lon: coordinate.longitude, lon: coordinate.longitude,
addedBy: await settingsService.user.email addedBy: settingsService.user.email
) )
} }

View File

@ -10,6 +10,7 @@ import SwiftLocation
import CoreLocation import CoreLocation
import Mockable import Mockable
@MainActor
@Mockable @Mockable
public protocol SwiftLocationProtocol { public protocol SwiftLocationProtocol {
@ -21,3 +22,8 @@ public protocol SwiftLocationProtocol {
} }
extension Location: SwiftLocationProtocol { } extension Location: SwiftLocationProtocol { }
// Force sendable conformance for SwiftLocation types
extension Tasks.ContinuousUpdateLocation.StreamEvent: @retroactive @unchecked Sendable { }
extension LocationPermission: @retroactive @unchecked Sendable { }
extension AccuracyFilter: @retroactive @unchecked Sendable { }

View File

@ -6,7 +6,7 @@
// Copyright © 2025 Selim Mustafaev. All rights reserved. // Copyright © 2025 Selim Mustafaev. All rights reserved.
// //
public enum DbUpdatePolicy: CaseIterable { public enum DbUpdatePolicy: CaseIterable, Sendable {
case always case always
case ifExists case ifExists

View File

@ -44,19 +44,19 @@ public extension StorageService {
func edit(event: VehicleEventDto, for number: String) async throws -> VehicleDto { func edit(event: VehicleEventDto, for number: String) async throws -> VehicleDto {
guard let vehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) else {
throw StorageError.vehicleNotFound
}
try await realm.asyncWrite { try await realm.asyncWrite {
guard let vehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) else {
throw StorageError.vehicleNotFound
}
if vehicle.events.contains(where: { $0.id == event.id }) { if vehicle.events.contains(where: { $0.id == event.id }) {
realm.add(VehicleEvent(dto: event), update: .modified) realm.add(VehicleEvent(dto: event), update: .modified)
vehicle.updatedDate = Date().timeIntervalSince1970 vehicle.updatedDate = Date().timeIntervalSince1970
} else { } else {
throw StorageError.eventNotFound throw StorageError.eventNotFound
} }
return vehicle.dto
} }
return vehicle.dto
} }
} }

View File

@ -28,20 +28,20 @@ extension StorageService {
public func deleteNote(id: String, for number: String) async throws -> VehicleDto { public func deleteNote(id: String, for number: String) async throws -> VehicleDto {
guard let vehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) else {
throw StorageError.vehicleNotFound
}
guard let realmNote = realm.object(ofType: VehicleNote.self, forPrimaryKey: id) else {
throw StorageError.noteNotFound
}
try await realm.asyncWrite { try await realm.asyncWrite {
guard let vehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) else {
throw StorageError.vehicleNotFound
}
guard let realmNote = realm.object(ofType: VehicleNote.self, forPrimaryKey: id) else {
throw StorageError.noteNotFound
}
realm.delete(realmNote) realm.delete(realmNote)
vehicle.updatedDate = Date().timeIntervalSince1970 vehicle.updatedDate = Date().timeIntervalSince1970
return vehicle.dto
} }
return vehicle.dto
} }
public func editNote(id: String, text: String, for number: String) async throws -> VehicleDto { public func editNote(id: String, text: String, for number: String) async throws -> VehicleDto {

View File

@ -17,8 +17,15 @@ public actor StorageService: StorageServiceProtocol {
public init(settingsService: SettingsServiceProtocol, isTest: Bool = false) async throws { public init(settingsService: SettingsServiceProtocol, isTest: Bool = false) async throws {
var realmConfig: Realm.Configuration self.settingsService = settingsService
realm = try await setup(isTest: isTest)
}
// Swift 6.0 and 6.1 crashes if this code is placed directly into init
private func setup(isTest: Bool) async throws -> Realm {
var realmConfig: Realm.Configuration
if isTest { if isTest {
realmConfig = .defaultConfiguration realmConfig = .defaultConfiguration
realmConfig.inMemoryIdentifier = UUID().uuidString realmConfig.inMemoryIdentifier = UUID().uuidString
@ -28,9 +35,8 @@ public actor StorageService: StorageServiceProtocol {
migrationBlock: { migration, oldSchemaVersion in } migrationBlock: { migration, oldSchemaVersion in }
) )
} }
self.settingsService = settingsService return try await Realm.open(configuration: realmConfig)
realm = try await Realm(configuration: realmConfig, actor: self)
} }
public var dbFileURL: URL? { public var dbFileURL: URL? {

View File

@ -2,7 +2,7 @@ import Foundation
public enum Constants { public enum Constants {
public enum Backend: String, CaseIterable { public enum Backend: String, CaseIterable, Sendable {
case de = "https://vps.aliencat.pro:8443/" case de = "https://vps.aliencat.pro:8443/"
case ru = "https://charon.aliencat.pro:8443/" case ru = "https://charon.aliencat.pro:8443/"

View File

@ -36,6 +36,18 @@ struct VehicleRecordServiceTests {
locationService: locationServiceMock, locationService: locationServiceMock,
settingsService: settingsServiceMock settingsService: settingsServiceMock
) )
given(settingsServiceMock)
.recognizeAlternativeOrder
.willReturn(false)
given(settingsServiceMock)
.recognizeShortenedNumbers
.willReturn(false)
given(settingsServiceMock)
.defaultRegion
.willReturn("")
} }
@Test("Requesting permissions") @Test("Requesting permissions")

View File

@ -29,13 +29,13 @@ struct EventsTests {
storageServiceMock = MockStorageServiceProtocol() storageServiceMock = MockStorageServiceProtocol()
apiServiceMock = MockApiServiceProtocol() apiServiceMock = MockApiServiceProtocol()
given(settingsServiceMock)
.user.willReturn(User())
viewModel = EventsViewModel(apiService: apiServiceMock, viewModel = EventsViewModel(apiService: apiServiceMock,
storageService: storageServiceMock, storageService: storageServiceMock,
settingsService: settingsServiceMock, settingsService: settingsServiceMock,
vehicle: VehicleDto()) vehicle: VehicleDto())
given(settingsServiceMock)
.user.willReturn(User())
} }
func makeViewModel(vehicle: VehicleDto) -> EventsViewModel { func makeViewModel(vehicle: VehicleDto) -> EventsViewModel {