diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7114c43 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +### macOS +# Finder metadata +.DS_Store + +# Thumbnails +._* + +# Custom folder icons +Icon + +# Volume root files +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +### Swift +# Xcode user settings +xcuserdata/ + +# Xcode build data +DerivedData/ + +# Swift/Obj-C specific +*.hmap + +# App packaging +*.ipa +*.dSYM.zip +*.dSYM + +# Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# Package.resolved \ No newline at end of file diff --git a/medmap.xcodeproj/project.pbxproj b/medmap.xcodeproj/project.pbxproj index 0315e84..96eea81 100644 --- a/medmap.xcodeproj/project.pbxproj +++ b/medmap.xcodeproj/project.pbxproj @@ -6,6 +6,12 @@ objectVersion = 77; objects = { +/* Begin PBXBuildFile section */ + 535766DE303F8E7C005C664E /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 535766DD303F8E7C005C664E /* GRDB */; }; + 535766E1303F8EAF005C664E /* Swinject in Frameworks */ = {isa = PBXBuildFile; productRef = 535766E0303F8EAF005C664E /* Swinject */; }; + 535766E7303F8F11005C664E /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 535766E6303F8F11005C664E /* Alamofire */; }; +/* End PBXBuildFile section */ + /* Begin PBXContainerItemProxy section */ 53AF151A303F8BCD00326308 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -52,6 +58,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 535766E7303F8F11005C664E /* Alamofire in Frameworks */, + 535766DE303F8E7C005C664E /* GRDB in Frameworks */, + 535766E1303F8EAF005C664E /* Swinject in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -112,6 +121,9 @@ ); name = medmap; packageProductDependencies = ( + 535766DD303F8E7C005C664E /* GRDB */, + 535766E0303F8EAF005C664E /* Swinject */, + 535766E6303F8F11005C664E /* Alamofire */, ); productName = medmap; productReference = 53AF150A303F8BCB00326308 /* medmap.app */; @@ -195,6 +207,11 @@ ); mainGroup = 53AF1501303F8BCB00326308; minimizedProjectReferenceProxies = 1; + packageReferences = ( + 535766DC303F8E7C005C664E /* XCRemoteSwiftPackageReference "GRDB.swift" */, + 535766DF303F8EAF005C664E /* XCRemoteSwiftPackageReference "Swinject" */, + 535766E5303F8F10005C664E /* XCRemoteSwiftPackageReference "Alamofire" */, + ); preferredProjectObjectVersion = 77; productRefGroup = 53AF150B303F8BCB00326308 /* Products */; projectDirPath = ""; @@ -397,7 +414,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 494F8GU77B; + DEVELOPMENT_TEAM = KNLHKLUVSG; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -410,7 +427,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = net.desynced.medmap; + PRODUCT_BUNDLE_IDENTIFIER = fr.cgd.cgdmobile; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_APPROACHABLE_CONCURRENCY = YES; @@ -429,7 +446,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 494F8GU77B; + DEVELOPMENT_TEAM = KNLHKLUVSG; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -442,7 +459,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = net.desynced.medmap; + PRODUCT_BUNDLE_IDENTIFIER = fr.cgd.cgdmobile; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_APPROACHABLE_CONCURRENCY = YES; @@ -578,6 +595,51 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 535766DC303F8E7C005C664E /* XCRemoteSwiftPackageReference "GRDB.swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/groue/GRDB.swift.git"; + requirement = { + branch = master; + kind = branch; + }; + }; + 535766DF303F8EAF005C664E /* XCRemoteSwiftPackageReference "Swinject" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Swinject/Swinject.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.10.0; + }; + }; + 535766E5303F8F10005C664E /* XCRemoteSwiftPackageReference "Alamofire" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Alamofire/Alamofire.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.12.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 535766DD303F8E7C005C664E /* GRDB */ = { + isa = XCSwiftPackageProductDependency; + package = 535766DC303F8E7C005C664E /* XCRemoteSwiftPackageReference "GRDB.swift" */; + productName = GRDB; + }; + 535766E0303F8EAF005C664E /* Swinject */ = { + isa = XCSwiftPackageProductDependency; + package = 535766DF303F8EAF005C664E /* XCRemoteSwiftPackageReference "Swinject" */; + productName = Swinject; + }; + 535766E6303F8F11005C664E /* Alamofire */ = { + isa = XCSwiftPackageProductDependency; + package = 535766E5303F8F10005C664E /* XCRemoteSwiftPackageReference "Alamofire" */; + productName = Alamofire; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 53AF1502303F8BCB00326308 /* Project object */; } diff --git a/medmap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/medmap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..8877179 --- /dev/null +++ b/medmap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,33 @@ +{ + "originHash" : "cea4493d312ae4e66e8286094daced88eff3c6aa100a666c34160384501a9b27", + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "7595cbcf59809f9977c5f6378500de2ad73b7ddb", + "version" : "5.12.0" + } + }, + { + "identity" : "grdb.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/groue/GRDB.swift.git", + "state" : { + "branch" : "master", + "revision" : "0d8cf958b4b66a0473ec6e6986eb9da462171da9" + } + }, + { + "identity" : "swinject", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Swinject/Swinject.git", + "state" : { + "revision" : "b685b549fe4d8ae265fc7a2f27d0789720425d69", + "version" : "2.10.0" + } + } + ], + "version" : 3 +} diff --git a/medmap/DependencyInjection/DIContainer.swift b/medmap/DependencyInjection/DIContainer.swift new file mode 100755 index 0000000..bc47f3e --- /dev/null +++ b/medmap/DependencyInjection/DIContainer.swift @@ -0,0 +1,47 @@ +// Copyright © 2024 VOID Software SA. All rights reserved. + +import Foundation +import Swinject + +final class DIContainer { + static var shared = DIContainer(isMocking: false) + let container: Container = Container() + let assembler: Assembler + + init(isMocking: Bool) { + + if !isMocking { + + assembler = Assembler( + [ + ManagerAssembly(), + RepositoriesAssembly(), + ViewModelsAssembly() + + ], + container: container + ) + } else { + assembler = Assembler( + [ + + ], + container: container + ) + } + } + + func resolve() -> T { + guard let resolvedType = container.resolve(T.self) else { + fatalError("Could not resolve dependency") + } + return resolvedType + } + + func resolve(argument: Arg) -> T { + guard let resolvedType = container.resolve(T.self, argument: argument) else { + fatalError("Could not resolve dependency (3)") + } + return resolvedType + } +} diff --git a/medmap/DependencyInjection/ManagersAssembly.swift b/medmap/DependencyInjection/ManagersAssembly.swift new file mode 100755 index 0000000..02a3845 --- /dev/null +++ b/medmap/DependencyInjection/ManagersAssembly.swift @@ -0,0 +1,72 @@ +// Copyright © 2025 VOID Software SA. All rights reserved. + +import Foundation +import Swinject + +final class ManagerAssembly: Assembly { + + func assemble(container: Container) { + + /* + + + container.register(AppStateManager.self) { _ in + return AppStateManager() + } + .inObjectScope(.container) + + container.register(GRDBDatabaseManager.self) { _ in + return GRDBDatabaseManager() + } + .inObjectScope(.container) + + container.register(ComicsBooksManager.self) { _ in + return ComicsBooksManager() + } + .inObjectScope(.container) + container.register(EventsManager.self) { _ in + return EventsManager() + } + .inObjectScope(.container) + + // API Client + container.register(AuthorizationInterceptor.self) { _ in + return AuthorizationInterceptor() + } + .inObjectScope(.container) + + container.register(APIClient.self) { _ in + return APIClient() + } + .inObjectScope(.container) + + container.register(EventsManager.self) { _ in + return EventsManager() + } + .inObjectScope(.container) + container.register(EntityDetector.self) { _ in + return EntityDetector() + } + .inObjectScope(.container) + + container.register(FileSystemManager.self) { _ in + return FileSystemManager() + } + .inObjectScope(.container) + + container.register(FluxReaderAPI.self) { _ in + return FluxReaderAPI() + } + .inObjectScope(.container) + container.register(PreferencesManager.self) { _ in + return PreferencesManager() + } + .inObjectScope(.container) + + container.register(NetworkMonitor.self) { _ in + return NetworkMonitor() + } + .inObjectScope(.container) + */ + } +} diff --git a/medmap/DependencyInjection/RepositoriesAssembly.swift b/medmap/DependencyInjection/RepositoriesAssembly.swift new file mode 100644 index 0000000..368e1fe --- /dev/null +++ b/medmap/DependencyInjection/RepositoriesAssembly.swift @@ -0,0 +1,79 @@ +// +// RepositoriesAssembly.swift +// FluxRead +// +// Created by RSA on 18/02/2026. +// + +import Foundation +import Swinject + +final class RepositoriesAssembly: Assembly { + + func assemble(container: Container) { + + /* + + container.register(ComicBooksRepository.self) { _ in + return ComicBooksRepository() + } + .inObjectScope(.container) + + container.register(ComicBookMetaDataAttributeRelationRepository.self) { _ in + return ComicBookMetaDataAttributeRelationRepository() + } + .inObjectScope(.container) + + container.register(ComicBookMetadataRepository.self) { _ in + return ComicBookMetadataRepository() + } + .inObjectScope(.container) + + container.register(ComicBookPageReadingStatRepository.self) { _ in + return ComicBookPageReadingStatRepository() + } + .inObjectScope(.container) + + container.register(ComicBookPagesRepository.self) { _ in + return ComicBookPagesRepository() + } + .inObjectScope(.container) + + container.register(GRDBComicBookPagePanelsRepository.self) { _ in + return GRDBComicBookPagePanelsRepository() + } + .inObjectScope(.container) + + container.register(GRDBComicBookPagePanelTextRepository.self) { _ in + return GRDBComicBookPagePanelTextRepository() + } + .inObjectScope(.container) + + container.register(LibraryImportProviderRepository.self) { _ in + return LibraryImportProviderRepository() + } + .inObjectScope(.container) + + container.register(ComicBookMetaDataAttributeRepository.self) { _ in + return ComicBookMetaDataAttributeRepository() + } + .inObjectScope(.container) + + container.register(UserActivityRepository.self) { _ in + return UserActivityRepository() + } + .inObjectScope(.container) + + container.register(SavedSearchComicRepository.self) { _ in + return SavedSearchComicRepository() + } + .inObjectScope(.container) + + container.register(SavedSearchRepository.self) { _ in + return SavedSearchRepository() + } + .inObjectScope(.container) + + */ + } +} diff --git a/medmap/DependencyInjection/ViewModelsAssembly.swift b/medmap/DependencyInjection/ViewModelsAssembly.swift new file mode 100644 index 0000000..a2db437 --- /dev/null +++ b/medmap/DependencyInjection/ViewModelsAssembly.swift @@ -0,0 +1,28 @@ +// +// ViewModelsAssembly.swift +// FluxRead +// +// Created by RSA on 18/02/2026. +// + +import Foundation +import Swinject + +final class ViewModelsAssembly: Assembly { + + func assemble(container: Container) { + + /* + container.register(SearchViewModel.self) { _ in + return SearchViewModel() + } + .inObjectScope(.container) + + container.register(MainViewModel.self) { _ in + return MainViewModel() + } + .inObjectScope(.container) + */ + + } +}