diff --git a/Example/Example.xcodeproj/Example.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/Example.xcodeproj/Example.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..925ac27 --- /dev/null +++ b/Example/Example.xcodeproj/Example.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,25 @@ +{ + "object": { + "pins": [ + { + "package": "Alamofire", + "repositoryURL": "https://github.com/Alamofire/Alamofire", + "state": { + "branch": null, + "revision": "78424be314842833c04bc3bef5b72e85fff99204", + "version": "5.6.4" + } + }, + { + "package": "AnyCodable", + "repositoryURL": "https://github.com/Flight-School/AnyCodable", + "state": { + "branch": null, + "revision": "862808b2070cd908cb04f9aafe7de83d35f81b05", + "version": "0.6.7" + } + } + ] + }, + "version": 1 +} diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 743e7bb..26e9e86 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -7,47 +7,46 @@ objects = { /* Begin PBXBuildFile section */ + 210D99FE2B0230FF00D568B1 /* InAppSettingsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 210D99FD2B0230FF00D568B1 /* InAppSettingsKit */; }; + 210D9A002B02314000D568B1 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 210D99FF2B02314000D568B1 /* Settings.bundle */; }; + 210D9A022B02437200D568B1 /* SettingsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210D9A012B02437200D568B1 /* SettingsManager.swift */; }; 211834CE29CDBAB2002F2CCD /* AsyncApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211834CD29CDBAB2002F2CCD /* AsyncApiUtils.swift */; }; 211834DB29CDEFF8002F2CCD /* Contents.json in Resources */ = {isa = PBXBuildFile; fileRef = 211834D829CDEFF8002F2CCD /* Contents.json */; }; 211834E129CDF08F002F2CCD /* ClientAppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211834DE29CDF08F002F2CCD /* ClientAppError.swift */; }; 211834E229CDF08F002F2CCD /* CancellableApiTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211834DF29CDF08F002F2CCD /* CancellableApiTask.swift */; }; 211834E329CDF08F002F2CCD /* TaskManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211834E029CDF08F002F2CCD /* TaskManager.swift */; }; - 211834E729CDF0A8002F2CCD /* AsyncApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211834E529CDF0A8002F2CCD /* AsyncApiUtils.swift */; }; 211834E829CDF0A8002F2CCD /* AlertUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211834E629CDF0A8002F2CCD /* AlertUtils.swift */; }; 2136DD4A274B9E74007B9FC9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2136DD49274B9E74007B9FC9 /* AppDelegate.swift */; }; 2136DD4C274B9E74007B9FC9 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2136DD4B274B9E74007B9FC9 /* SceneDelegate.swift */; }; - 2136DD4E274B9E74007B9FC9 /* VideosViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2136DD4D274B9E74007B9FC9 /* VideosViewController.swift */; }; 2136DD51274B9E74007B9FC9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2136DD4F274B9E74007B9FC9 /* Main.storyboard */; }; 2136DD53274B9E77007B9FC9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2136DD52274B9E77007B9FC9 /* Assets.xcassets */; }; 2136DD56274B9E77007B9FC9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2136DD54274B9E77007B9FC9 /* LaunchScreen.storyboard */; }; + 21F366322B02695B00416B65 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F366312B02695B00416B65 /* UIColorExtensions.swift */; }; C76439BC27A2F69F007FB307 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C76439BB27A2F69F007FB307 /* XCTest.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; C7BC280227A16604007406AB /* ApiVideoClient in Frameworks */ = {isa = PBXBuildFile; productRef = C7BC280127A16604007406AB /* ApiVideoClient */; }; C7BC280427A17CD2007406AB /* UploaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7BC280327A17CD2007406AB /* UploaderViewController.swift */; }; - C7BC280727A17FEB007406AB /* VideoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7BC280627A17FEB007406AB /* VideoTableViewCell.swift */; }; - C7BC280A27A18CC3007406AB /* ClientManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7BC280927A18CC3007406AB /* ClientManager.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 211834CD29CDBAB2002F2CCD /* AsyncApiUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AsyncApiUtils.swift; path = Utils/AsyncApiUtils.swift; sourceTree = ""; }; + 210D99FF2B02314000D568B1 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; + 210D9A012B02437200D568B1 /* SettingsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsManager.swift; sourceTree = ""; }; + 211834CD29CDBAB2002F2CCD /* AsyncApiUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncApiUtils.swift; sourceTree = ""; }; 211834D829CDEFF8002F2CCD /* Contents.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Contents.json; path = Assets.xcassets/Contents.json; sourceTree = ""; }; 211834DE29CDF08F002F2CCD /* ClientAppError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClientAppError.swift; sourceTree = ""; }; 211834DF29CDF08F002F2CCD /* CancellableApiTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancellableApiTask.swift; sourceTree = ""; }; 211834E029CDF08F002F2CCD /* TaskManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskManager.swift; sourceTree = ""; }; - 211834E529CDF0A8002F2CCD /* AsyncApiUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncApiUtils.swift; sourceTree = ""; }; 211834E629CDF0A8002F2CCD /* AlertUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertUtils.swift; sourceTree = ""; }; 2136DD46274B9E74007B9FC9 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2136DD49274B9E74007B9FC9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 2136DD4B274B9E74007B9FC9 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 2136DD4D274B9E74007B9FC9 /* VideosViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosViewController.swift; sourceTree = ""; }; 2136DD50274B9E74007B9FC9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 2136DD52274B9E77007B9FC9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2136DD55274B9E77007B9FC9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 2136DD57274B9E77007B9FC9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2136DD5F274B9EED007B9FC9 /* swift5 */ = {isa = PBXFileReference; lastKnownFileType = folder; name = swift5; path = ..; sourceTree = ""; }; + 21F366312B02695B00416B65 /* UIColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; C76439BB27A2F69F007FB307 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C7BC280327A17CD2007406AB /* UploaderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploaderViewController.swift; sourceTree = ""; }; - C7BC280627A17FEB007406AB /* VideoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoTableViewCell.swift; sourceTree = ""; }; - C7BC280927A18CC3007406AB /* ClientManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientManager.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,6 +55,7 @@ buildActionMask = 2147483647; files = ( C76439BC27A2F69F007FB307 /* XCTest.framework in Frameworks */, + 210D99FE2B0230FF00D568B1 /* InAppSettingsKit in Frameworks */, C7BC280227A16604007406AB /* ApiVideoClient in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -76,8 +76,10 @@ 211834E429CDF0A8002F2CCD /* Utils */ = { isa = PBXGroup; children = ( - 211834E529CDF0A8002F2CCD /* AsyncApiUtils.swift */, + 211834CD29CDBAB2002F2CCD /* AsyncApiUtils.swift */, + 210D9A012B02437200D568B1 /* SettingsManager.swift */, 211834E629CDF0A8002F2CCD /* AlertUtils.swift */, + 21F366312B02695B00416B65 /* UIColorExtensions.swift */, ); path = Utils; sourceTree = ""; @@ -103,19 +105,17 @@ 2136DD48274B9E74007B9FC9 /* Example */ = { isa = PBXGroup; children = ( + 210D99FF2B02314000D568B1 /* Settings.bundle */, 211834E429CDF0A8002F2CCD /* Utils */, 211834DD29CDF08F002F2CCD /* Models */, 211834D829CDEFF8002F2CCD /* Contents.json */, C7BC280827A18111007406AB /* ViewControllers */, - C7BC280527A17FD4007406AB /* Cell */, 2136DD49274B9E74007B9FC9 /* AppDelegate.swift */, 2136DD4B274B9E74007B9FC9 /* SceneDelegate.swift */, 2136DD4F274B9E74007B9FC9 /* Main.storyboard */, 2136DD52274B9E77007B9FC9 /* Assets.xcassets */, 2136DD54274B9E77007B9FC9 /* LaunchScreen.storyboard */, 2136DD57274B9E77007B9FC9 /* Info.plist */, - C7BC280927A18CC3007406AB /* ClientManager.swift */, - 211834CD29CDBAB2002F2CCD /* AsyncApiUtils.swift */, ); path = Example; sourceTree = ""; @@ -136,18 +136,9 @@ name = Frameworks; sourceTree = ""; }; - C7BC280527A17FD4007406AB /* Cell */ = { - isa = PBXGroup; - children = ( - C7BC280627A17FEB007406AB /* VideoTableViewCell.swift */, - ); - path = Cell; - sourceTree = ""; - }; C7BC280827A18111007406AB /* ViewControllers */ = { isa = PBXGroup; children = ( - 2136DD4D274B9E74007B9FC9 /* VideosViewController.swift */, C7BC280327A17CD2007406AB /* UploaderViewController.swift */, ); path = ViewControllers; @@ -171,6 +162,7 @@ name = Example; packageProductDependencies = ( C7BC280127A16604007406AB /* ApiVideoClient */, + 210D99FD2B0230FF00D568B1 /* InAppSettingsKit */, ); productName = Example; productReference = 2136DD46274B9E74007B9FC9 /* Example.app */; @@ -200,6 +192,9 @@ Base, ); mainGroup = 2136DD3D274B9E74007B9FC9; + packageReferences = ( + 210D99FC2B0230FF00D568B1 /* XCRemoteSwiftPackageReference "InAppSettingsKit" */, + ); productRefGroup = 2136DD47274B9E74007B9FC9 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -216,6 +211,7 @@ files = ( 2136DD56274B9E77007B9FC9 /* LaunchScreen.storyboard in Resources */, 2136DD53274B9E77007B9FC9 /* Assets.xcassets in Resources */, + 210D9A002B02314000D568B1 /* Settings.bundle in Resources */, 2136DD51274B9E74007B9FC9 /* Main.storyboard in Resources */, 211834DB29CDEFF8002F2CCD /* Contents.json in Resources */, ); @@ -228,18 +224,16 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2136DD4E274B9E74007B9FC9 /* VideosViewController.swift in Sources */, 211834E129CDF08F002F2CCD /* ClientAppError.swift in Sources */, 211834CE29CDBAB2002F2CCD /* AsyncApiUtils.swift in Sources */, 2136DD4A274B9E74007B9FC9 /* AppDelegate.swift in Sources */, - C7BC280A27A18CC3007406AB /* ClientManager.swift in Sources */, C7BC280427A17CD2007406AB /* UploaderViewController.swift in Sources */, - 211834E729CDF0A8002F2CCD /* AsyncApiUtils.swift in Sources */, 211834E829CDF0A8002F2CCD /* AlertUtils.swift in Sources */, + 210D9A022B02437200D568B1 /* SettingsManager.swift in Sources */, 2136DD4C274B9E74007B9FC9 /* SceneDelegate.swift in Sources */, 211834E229CDF08F002F2CCD /* CancellableApiTask.swift in Sources */, 211834E329CDF08F002F2CCD /* TaskManager.swift in Sources */, - C7BC280727A17FEB007406AB /* VideoTableViewCell.swift in Sources */, + 21F366322B02695B00416B65 /* UIColorExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -462,7 +456,23 @@ }; /* End XCConfigurationList section */ +/* Begin XCRemoteSwiftPackageReference section */ + 210D99FC2B0230FF00D568B1 /* XCRemoteSwiftPackageReference "InAppSettingsKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/futuretap/InAppSettingsKit.git"; + requirement = { + kind = exactVersion; + version = 3.4.2; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + /* Begin XCSwiftPackageProductDependency section */ + 210D99FD2B0230FF00D568B1 /* InAppSettingsKit */ = { + isa = XCSwiftPackageProductDependency; + package = 210D99FC2B0230FF00D568B1 /* XCRemoteSwiftPackageReference "InAppSettingsKit" */; + productName = InAppSettingsKit; + }; C7BC280127A16604007406AB /* ApiVideoClient */ = { isa = XCSwiftPackageProductDependency; productName = ApiVideoClient; diff --git a/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 65f7c57..9ceff65 100644 --- a/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -18,6 +18,15 @@ "revision": "b1a7a8a6186f2fcb28f7bda67cfc545de48b3c80", "version": "0.6.2" } + }, + { + "package": "InAppSettingsKit", + "repositoryURL": "https://github.com/futuretap/InAppSettingsKit.git", + "state": { + "branch": null, + "revision": "08ab93cd15759eed534b821c2ea789d97a0fdca0", + "version": "3.4.2" + } } ] }, diff --git a/Example/Example/AppDelegate.swift b/Example/Example/AppDelegate.swift index 92ed19d..47dbaf8 100644 --- a/Example/Example/AppDelegate.swift +++ b/Example/Example/AppDelegate.swift @@ -8,8 +8,6 @@ import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/1024.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/1024.png new file mode 100644 index 0000000..3fff53b Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/120 1.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/120 1.png new file mode 100644 index 0000000..49405f4 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/120 1.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/120 2.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/120 2.png new file mode 100644 index 0000000..49405f4 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/120 2.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/152.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/152.png new file mode 100644 index 0000000..28adb6b Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/152.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/167.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/167.png new file mode 100644 index 0000000..298d0c6 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/167.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/180.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/180.png new file mode 100644 index 0000000..ff08a37 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/180.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/20.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/20.png new file mode 100644 index 0000000..b88c87b Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/20.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/29.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/29.png new file mode 100644 index 0000000..fbd42b9 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/29.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/40 1.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/40 1.png new file mode 100644 index 0000000..af2c141 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/40 1.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/40 2.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/40 2.png new file mode 100644 index 0000000..af2c141 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/40 2.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/40.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/40.png new file mode 100644 index 0000000..af2c141 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/40.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/58 1.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/58 1.png new file mode 100644 index 0000000..110dac7 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/58 1.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/58.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/58.png new file mode 100644 index 0000000..110dac7 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/58.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/60.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/60.png new file mode 100644 index 0000000..683adad Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/60.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/76.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/76.png new file mode 100644 index 0000000..60f8825 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/76.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/80 1.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/80 1.png new file mode 100644 index 0000000..9dfb993 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/80 1.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/80.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/80.png new file mode 100644 index 0000000..9dfb993 Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/80.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/87.png b/Example/Example/Assets.xcassets/AppIcon.appiconset/87.png new file mode 100644 index 0000000..d564d5d Binary files /dev/null and b/Example/Example/Assets.xcassets/AppIcon.appiconset/87.png differ diff --git a/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json index 9221b9b..83e2c62 100644 --- a/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,91 +1,109 @@ { "images" : [ { + "filename" : "40.png", "idiom" : "iphone", "scale" : "2x", "size" : "20x20" }, { + "filename" : "60.png", "idiom" : "iphone", "scale" : "3x", "size" : "20x20" }, { + "filename" : "58 1.png", "idiom" : "iphone", "scale" : "2x", "size" : "29x29" }, { + "filename" : "87.png", "idiom" : "iphone", "scale" : "3x", "size" : "29x29" }, { + "filename" : "80 1.png", "idiom" : "iphone", "scale" : "2x", "size" : "40x40" }, { + "filename" : "120 2.png", "idiom" : "iphone", "scale" : "3x", "size" : "40x40" }, { + "filename" : "120 1.png", "idiom" : "iphone", "scale" : "2x", "size" : "60x60" }, { + "filename" : "180.png", "idiom" : "iphone", "scale" : "3x", "size" : "60x60" }, { + "filename" : "20.png", "idiom" : "ipad", "scale" : "1x", "size" : "20x20" }, { + "filename" : "40 1.png", "idiom" : "ipad", "scale" : "2x", "size" : "20x20" }, { + "filename" : "29.png", "idiom" : "ipad", "scale" : "1x", "size" : "29x29" }, { + "filename" : "58.png", "idiom" : "ipad", "scale" : "2x", "size" : "29x29" }, { + "filename" : "40 2.png", "idiom" : "ipad", "scale" : "1x", "size" : "40x40" }, { + "filename" : "80.png", "idiom" : "ipad", "scale" : "2x", "size" : "40x40" }, { + "filename" : "76.png", "idiom" : "ipad", "scale" : "1x", "size" : "76x76" }, { + "filename" : "152.png", "idiom" : "ipad", "scale" : "2x", "size" : "76x76" }, { + "filename" : "167.png", "idiom" : "ipad", "scale" : "2x", "size" : "83.5x83.5" }, { + "filename" : "1024.png", "idiom" : "ios-marketing", "scale" : "1x", "size" : "1024x1024" diff --git a/Example/Example/Base.lproj/Assets.xcassets/AccentColor.colorset/Contents.json b/Example/Example/Base.lproj/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Example/Example/Base.lproj/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/Example/Base.lproj/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/Example/Base.lproj/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/Example/Example/Base.lproj/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/Example/Base.lproj/Assets.xcassets/Contents.json b/Example/Example/Base.lproj/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/Example/Base.lproj/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/Example/Base.lproj/Main.storyboard b/Example/Example/Base.lproj/Main.storyboard index ba2c177..30aa2a0 100644 --- a/Example/Example/Base.lproj/Main.storyboard +++ b/Example/Example/Base.lproj/Main.storyboard @@ -1,51 +1,14 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -62,37 +25,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - + - - - diff --git a/Example/Example/Cell/VideoTableViewCell.swift b/Example/Example/Cell/VideoTableViewCell.swift deleted file mode 100644 index b1eed5a..0000000 --- a/Example/Example/Cell/VideoTableViewCell.swift +++ /dev/null @@ -1,102 +0,0 @@ -// -// VideoTableViewCell.swift -// Example -// - -import UIKit -import ApiVideoClient - -class VideoTableViewCell: UITableViewCell { - - static let identifier = "VideoTableViewCell" - - private let title: UILabel = { - let label = UILabel() - label.numberOfLines = 1 - return label - }() - private let videoId: UILabel = { - let label = UILabel() - label.numberOfLines = 1 - return label - }() - - private let thumbnailView: UIImageView = { - let imageView = UIImageView() - return imageView - }() - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - contentView.addSubview(title) - contentView.addSubview(videoId) - contentView.addSubview(thumbnailView) - thumbnailView.contentMode = .scaleAspectFit - thumbnailView.backgroundColor = .black - contentView.clipsToBounds = true - accessoryType = .none - } - - required init?(coder: NSCoder) { - fatalError() - } - - override func layoutSubviews() { - super.layoutSubviews() - thumbnailView.frame = CGRect( - x: 10, - y: 5, - width: contentView.frame.size.width - 20, - height: contentView.frame.size.height * 0.7 - ) - - title.frame = CGRect( - x: 20, - y: (thumbnailView.frame.height * 0.6) + 55, - width: contentView.frame.size.width, - height: contentView.frame.size.height * 0.4 - ) - videoId.frame = CGRect( - x: 20, - y: (thumbnailView.frame.height * 0.6) + 80, - width: contentView.frame.size.width, - height: contentView.frame.size.height * 0.4 - ) - videoId.textColor = .lightGray - videoId.font = videoId.font.withSize(10) - } - - override func prepareForReuse() { - super.prepareForReuse() - title.text = nil - videoId.text = nil - } - - public func bind(with video: Video) { - title.text = video.title ?? "Unknown title" - videoId.text = video.videoId - - if let thumbnail = video.assets?.thumbnail { - do { - guard let thumbnailUrl = URL(string: thumbnail) else { - print("Invalid thumbnail url: \(thumbnail)") - return - } - fetchThumbnails(url: thumbnailUrl) - } catch { - print("Error while loading thumbnail: \(error)") - } - } - } - - private func fetchThumbnails(url: URL) { - Task { - do { - let (data, _) = try await URLSession.shared.data(from: url) - thumbnailView.image = UIImage(data: data) - } catch { - print("Error while loading thumbnail: \(error)") - } - } - } -} diff --git a/Example/Example/ClientManager.swift b/Example/Example/ClientManager.swift deleted file mode 100644 index 6f7a856..0000000 --- a/Example/Example/ClientManager.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// ClientManager.swift -// Example -// - -import Foundation -import ApiVideoClient - -class ClientManager { - public static var apiKey: String = "YOUR_API_KEY" - public static var environment: Environment = Environment.sandbox - - public static var isProduction: Bool { - get { - if (environment == Environment.production) { - return true - } else { - return false - } - } - } -} diff --git a/Example/Example/Settings.bundle/Root.plist b/Example/Example/Settings.bundle/Root.plist new file mode 100644 index 0000000..ff99fe6 --- /dev/null +++ b/Example/Example/Settings.bundle/Root.plist @@ -0,0 +1,47 @@ + + + + + StringsTable + Root + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Configuration + + + Type + PSTextFieldSpecifier + Title + API key + Key + ApiKey + DefaultValue + YOUR_API_KEY + + + Type + PSRadioGroupSpecifier + Title + Environment + Key + Environment + DefaultValue + 0 + Values + + 0 + 1 + + Titles + + Sandbox + Production + + + + + diff --git a/Example/Example/Settings.bundle/en.lproj/Root.strings b/Example/Example/Settings.bundle/en.lproj/Root.strings new file mode 100644 index 0000000..8cd87b9 Binary files /dev/null and b/Example/Example/Settings.bundle/en.lproj/Root.strings differ diff --git a/Example/Example/Utils/SettingsManager.swift b/Example/Example/Utils/SettingsManager.swift new file mode 100644 index 0000000..bd5465e --- /dev/null +++ b/Example/Example/Utils/SettingsManager.swift @@ -0,0 +1,18 @@ +import Foundation +import ApiVideoClient + +/// A static class to retrieve configuration from UserDefaults +enum SettingsManager { + static var apiKey: String { + UserDefaults.standard.string(forKey: "ApiKey") ?? "YOUR_API_KEY" + } + + static var environment: Environment { + let key = UserDefaults.standard.integer(forKey: "Environment") + if (key == 1) { + return Environment.production + } else { + return Environment.sandbox + } + } +} diff --git a/Example/Example/Utils/UIColorExtensions.swift b/Example/Example/Utils/UIColorExtensions.swift new file mode 100644 index 0000000..9df66e2 --- /dev/null +++ b/Example/Example/Utils/UIColorExtensions.swift @@ -0,0 +1,7 @@ +import Foundation +import UIKit + +extension UIColor { + static let orange = UIColor(red: 250/255, green: 91/255, blue: 48/255, alpha: 1) +} + diff --git a/Example/Example/ViewControllers/UploaderViewController.swift b/Example/Example/ViewControllers/UploaderViewController.swift index ce5eebb..ace8806 100644 --- a/Example/Example/ViewControllers/UploaderViewController.swift +++ b/Example/Example/ViewControllers/UploaderViewController.swift @@ -7,130 +7,70 @@ import UIKit import AVKit import ApiVideoClient import SwiftUI +import InAppSettingsKit class UploaderViewController: UIViewController { let imagePickerController = UIImagePickerController() + + /// Handle multiple upload tasks let taskManager = TaskManager() - let paramBackgroundView: UIView = { - let paramView = UIView() - return paramView - }() - let environmentTitleLabel: UILabel = { - let title = UILabel() - title.text = "Client configuration" - title.font = UIFont.systemFont(ofSize: 22, weight: .bold) - return title - }() - - let selectedEnvironmentLabel: UILabel = { - let title = UILabel() - title.text = "Production" - return title - }() - - let selectEnvironmentSwitch: UISwitch = { - let selectSwitch = UISwitch() - return selectSwitch - }() - - let apiKeyLabel: UILabel = { - let api = UILabel() - api.text = "Your Api key :" - return api - }() - - let apiKeyTextField: UITextField = { - let api = UITextField() - return api + /// Manage configuration + let iaskViewController: IASKAppSettingsViewController = { + let iaskViewController = IASKAppSettingsViewController() + iaskViewController.showCreditsFooter = false + iaskViewController.view.tintColor = UIColor.orange + return iaskViewController }() let videoPickerButton: UIButton = { let btn = UIButton(type: .system) btn.setTitle("Pick a video", for: .normal) + btn.tintColor = UIColor.orange return btn }() let cancelButton: UIButton = { let btn = UIButton(type: .system) btn.setTitle("Cancel all uploads", for: .normal) + btn.tintColor = UIColor.orange + btn.isHidden = true return btn }() override func viewDidLoad() { super.viewDidLoad() - configureClient() - title = "Uploader" - view.addSubview(paramBackgroundView) - - paramBackgroundView.backgroundColor = .darkGray - paramBackgroundView.layer.cornerRadius = 10 - paramBackgroundView.addSubview(environmentTitleLabel) - paramBackgroundView.addSubview(selectedEnvironmentLabel) - paramBackgroundView.addSubview(selectEnvironmentSwitch) - paramBackgroundView.addSubview(apiKeyLabel) - - paramBackgroundView.addSubview(apiKeyTextField) - apiKeyLabel.frame = CGRect(x: 0, y: 0, width: 105, height: 30) + + addChild(iaskViewController) + view.addSubview(iaskViewController.view) + view.addSubview(videoPickerButton) view.addSubview(cancelButton) videoPickerButton.addTarget(self, action: #selector(pickVideo), for: .touchUpInside) cancelButton.addTarget(self, action: #selector(cleanUploadQueue), for: .touchUpInside) - selectEnvironmentSwitch.addTarget(self, action: #selector(toggleSwitch), for: .touchUpInside) - - selectEnvironmentSwitch.isOn = ClientManager.isProduction - if (!selectEnvironmentSwitch.isOn) { - selectedEnvironmentLabel.text = "Sandbox" - } - - apiKeyTextField.delegate = self - apiKeyTextField.text = ClientManager.apiKey constraints() } func constraints() { - paramBackgroundView.translatesAutoresizingMaskIntoConstraints = false - environmentTitleLabel.translatesAutoresizingMaskIntoConstraints = false - selectedEnvironmentLabel.translatesAutoresizingMaskIntoConstraints = false - selectEnvironmentSwitch.translatesAutoresizingMaskIntoConstraints = false - apiKeyLabel.translatesAutoresizingMaskIntoConstraints = false - apiKeyTextField.translatesAutoresizingMaskIntoConstraints = false + iaskViewController.view.translatesAutoresizingMaskIntoConstraints = false videoPickerButton.translatesAutoresizingMaskIntoConstraints = false cancelButton.translatesAutoresizingMaskIntoConstraints = false - paramBackgroundView.widthAnchor.constraint(equalToConstant: view.frame.width - 20).isActive = true - paramBackgroundView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 30).isActive = true - paramBackgroundView.heightAnchor.constraint(equalToConstant: 150).isActive = true - paramBackgroundView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true - - environmentTitleLabel.centerXAnchor.constraint(equalTo: paramBackgroundView.centerXAnchor).isActive = true - environmentTitleLabel.topAnchor.constraint(equalTo: paramBackgroundView.topAnchor, constant: 10).isActive = true - - selectedEnvironmentLabel.topAnchor.constraint(equalTo: paramBackgroundView.topAnchor, constant: 50).isActive = true - selectedEnvironmentLabel.leftAnchor.constraint(equalTo: paramBackgroundView.leftAnchor, constant: 20).isActive = true - selectedEnvironmentLabel.widthAnchor.constraint(equalToConstant: (view.frame.width - 20) / 2).isActive = true - selectEnvironmentSwitch.centerYAnchor.constraint(equalTo: selectedEnvironmentLabel.centerYAnchor).isActive = true - selectEnvironmentSwitch.rightAnchor.constraint(equalTo: paramBackgroundView.rightAnchor, constant: -20).isActive = true - - - apiKeyLabel.topAnchor.constraint(equalTo: paramBackgroundView.topAnchor, constant: 80).isActive = true - apiKeyLabel.bottomAnchor.constraint(equalTo: paramBackgroundView.bottomAnchor).isActive = true - apiKeyLabel.leftAnchor.constraint(equalTo: paramBackgroundView.leftAnchor, constant: 20).isActive = true - - apiKeyTextField.centerYAnchor.constraint(equalTo: apiKeyLabel.centerYAnchor).isActive = true - apiKeyTextField.topAnchor.constraint(equalTo: paramBackgroundView.topAnchor, constant: 80).isActive = true - apiKeyTextField.bottomAnchor.constraint(equalTo: paramBackgroundView.bottomAnchor).isActive = true - apiKeyTextField.rightAnchor.constraint(equalTo: paramBackgroundView.rightAnchor, constant: -20).isActive = true - apiKeyTextField.widthAnchor.constraint(equalToConstant: 250).isActive = true - - videoPickerButton.widthAnchor.constraint(equalToConstant: 110).isActive = true + iaskViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + iaskViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true + iaskViewController.view.heightAnchor.constraint(equalToConstant: 300).isActive = true + iaskViewController.view.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + iaskViewController.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true + + videoPickerButton.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + videoPickerButton.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true videoPickerButton.heightAnchor.constraint(equalToConstant: 40).isActive = true videoPickerButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true - videoPickerButton.topAnchor.constraint(equalTo: apiKeyTextField.bottomAnchor, constant: 10).isActive = true + videoPickerButton.topAnchor.constraint(equalTo: iaskViewController.view.bottomAnchor, constant: 20).isActive = true cancelButton.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true cancelButton.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true @@ -139,11 +79,6 @@ class UploaderViewController: UIViewController { cancelButton.topAnchor.constraint(equalTo: videoPickerButton.bottomAnchor, constant: 10).isActive = true } - func configureClient() { - ApiVideoClient.apiKey = ClientManager.apiKey - ApiVideoClient.basePath = ClientManager.environment.rawValue - } - @objc func cleanUploadQueue() { taskManager.cancelAllTasks() } @@ -185,22 +120,6 @@ class UploaderViewController: UIViewController { let uploadedVideo = try await AsyncApiUtils.uploadVideo(videoId: video.videoId, url: fileUrl, progress: progress) print("Video uploaded: \(uploadedVideo)") } - - @objc func toggleSwitch() { - if (selectEnvironmentSwitch.isOn) { - ClientManager.environment = Environment.production - selectedEnvironmentLabel.text = "Production" - } else { - ClientManager.environment = Environment.sandbox - selectedEnvironmentLabel.text = "Sandbox" - } - } -} - -extension UploaderViewController: UITextFieldDelegate { - func textFieldDidEndEditing(_ textField: UITextField) { - ClientManager.apiKey = textField.text! - } } extension UploaderViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { @@ -209,7 +128,15 @@ extension UploaderViewController: UIImagePickerControllerDelegate, UINavigationC AlertUtils.show("No video selected", vc: self) return } - addToUploadQueue(videoUrl: url) + imagePickerController.dismiss(animated: true, completion: nil) + cancelButton.isHidden = false + + // Set client configuration + ApiVideoClient.apiKey = SettingsManager.apiKey + ApiVideoClient.basePath = SettingsManager.environment.rawValue + + // Upload + addToUploadQueue(videoUrl: url) } } diff --git a/Example/Example/ViewControllers/VideosViewController.swift b/Example/Example/ViewControllers/VideosViewController.swift deleted file mode 100644 index 4494276..0000000 --- a/Example/Example/ViewControllers/VideosViewController.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// ViewController.swift -// Example -// - -import UIKit -import ApiVideoClient - -class VideosViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { - private var videos = [Video]() - - private func requestVideos() { - Task { - do { - self.videos = try await AsyncApiUtils.getVideos() - self.tableView.reloadData() - } catch { - AlertUtils.show(error.localizedDescription, title: "List video error", vc: self) - } - } - } - - func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - let headerView = UIView() - headerView.backgroundColor = UIColor.clear - return headerView - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return videos.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let model = videos[indexPath.row] - - guard let cell = tableView.dequeueReusableCell(withIdentifier: VideoTableViewCell.identifier, for: indexPath) as? VideoTableViewCell else { - return UITableViewCell() - } - cell.layer.cornerRadius = 8 - cell.bind(with: model) - return cell - } - - - private let tableView: UITableView = { - let table = UITableView(frame: .zero, style: .grouped) - table.register(VideoTableViewCell.self, forCellReuseIdentifier: VideoTableViewCell.identifier) - return table - }() - - override func viewDidLoad() { - super.viewDidLoad() - title = "Videos" - view.addSubview(tableView) - tableView.delegate = self - tableView.dataSource = self - tableView.frame = view.bounds - tableView.rowHeight = 310.0 - - requestVideos() - } -} diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..925ac27 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,25 @@ +{ + "object": { + "pins": [ + { + "package": "Alamofire", + "repositoryURL": "https://github.com/Alamofire/Alamofire", + "state": { + "branch": null, + "revision": "78424be314842833c04bc3bef5b72e85fff99204", + "version": "5.6.4" + } + }, + { + "package": "AnyCodable", + "repositoryURL": "https://github.com/Flight-School/AnyCodable", + "state": { + "branch": null, + "revision": "862808b2070cd908cb04f9aafe7de83d35f81b05", + "version": "0.6.7" + } + } + ] + }, + "version": 1 +}