From b812ffe18a3ffe5cc9860f7daa98dfdcbff6706c Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 12:52:22 +0300 Subject: [PATCH 1/9] Remove Client-Type header --- Sources/Gravatar/Network/Services/AvatarService.swift | 4 ++-- Tests/GravatarTests/AvatarServiceTests.swift | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Sources/Gravatar/Network/Services/AvatarService.swift b/Sources/Gravatar/Network/Services/AvatarService.swift index 565b9964..b2dc4a8f 100644 --- a/Sources/Gravatar/Network/Services/AvatarService.swift +++ b/Sources/Gravatar/Network/Services/AvatarService.swift @@ -47,7 +47,7 @@ public struct AvatarService: Sendable { @discardableResult @available(*, deprecated, renamed: "upload(_:accessToken:)") public func upload(_ image: UIImage, email: Email, accessToken: String) async throws -> URLResponse { - try await imageUploader.uploadImage(image, accessToken: accessToken, additionalHTTPHeaders: [(name: "Client-Type", value: "ios")]).response + try await imageUploader.uploadImage(image, accessToken: accessToken, additionalHTTPHeaders: nil).response } /// Uploads an image to be used as the user's Gravatar profile image, and returns the `URLResponse` of the network tasks asynchronously. Throws @@ -59,7 +59,7 @@ public struct AvatarService: Sendable { @discardableResult public func upload(_ image: UIImage, accessToken: String) async throws -> Avatar { do { - let (data, _) = try await imageUploader.uploadImage(image, accessToken: accessToken, additionalHTTPHeaders: [(name: "Client-Type", value: "ios")]) + let (data, _) = try await imageUploader.uploadImage(image, accessToken: accessToken, additionalHTTPHeaders: nil) return try data.decode() } catch let error as ImageUploadError { throw error diff --git a/Tests/GravatarTests/AvatarServiceTests.swift b/Tests/GravatarTests/AvatarServiceTests.swift index ca1c1462..822cd18f 100644 --- a/Tests/GravatarTests/AvatarServiceTests.swift +++ b/Tests/GravatarTests/AvatarServiceTests.swift @@ -35,7 +35,6 @@ final class AvatarServiceTests: XCTestCase { XCTAssertTrue(request?.value(forHTTPHeaderField: "Authorization")?.hasPrefix("Bearer ") ?? false) XCTAssertNotNil(request?.value(forHTTPHeaderField: "Content-Type")) XCTAssertTrue(request?.value(forHTTPHeaderField: "Content-Type")?.hasPrefix("multipart/form-data; boundary=") ?? false) - XCTAssertTrue(request?.value(forHTTPHeaderField: "Client-Type") == "ios") } func testUploadImageError() async throws { From ee9229228f72d240f6ec772d83a34353c51c9a32 Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 15:06:50 +0300 Subject: [PATCH 2/9] Add SDKInfo.plist to update the version --- Package.swift | 1 + Sources/Gravatar/Info.swift | 8 ++++++++ Sources/Gravatar/Resources/SDKInfo.plist | 8 ++++++++ 3 files changed, 17 insertions(+) create mode 100644 Sources/Gravatar/Info.swift create mode 100644 Sources/Gravatar/Resources/SDKInfo.plist diff --git a/Package.swift b/Package.swift index 0431b86d..375317e6 100644 --- a/Package.swift +++ b/Package.swift @@ -32,6 +32,7 @@ let package = Package( // Targets can depend on other targets in this package and products from dependencies. .target( name: "Gravatar", + resources: [.process("Resources")], swiftSettings: [ .enableExperimentalFeature("StrictConcurrency") ], diff --git a/Sources/Gravatar/Info.swift b/Sources/Gravatar/Info.swift new file mode 100644 index 00000000..39ec5043 --- /dev/null +++ b/Sources/Gravatar/Info.swift @@ -0,0 +1,8 @@ +// +// File.swift +// +// +// Created by Pinar Olguc on 3.10.2024. +// + +import Foundation diff --git a/Sources/Gravatar/Resources/SDKInfo.plist b/Sources/Gravatar/Resources/SDKInfo.plist new file mode 100644 index 00000000..e1013fac --- /dev/null +++ b/Sources/Gravatar/Resources/SDKInfo.plist @@ -0,0 +1,8 @@ + + + + + CFBundleShortVersionString + 2.1.1 + + From f8e5e74956009a721ac34115fef396a1ef75799e Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 15:07:31 +0300 Subject: [PATCH 3/9] Add Info.swift --- Sources/Gravatar/Info.swift | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Sources/Gravatar/Info.swift b/Sources/Gravatar/Info.swift index 39ec5043..8e19d864 100644 --- a/Sources/Gravatar/Info.swift +++ b/Sources/Gravatar/Info.swift @@ -1,8 +1,22 @@ -// -// File.swift -// -// -// Created by Pinar Olguc on 3.10.2024. -// - import Foundation + +struct Info { + public static var sdkVersion: String? { + getInfoValue(forKey: "CFBundleShortVersionString") as? String + } + + public static var appName: String? { + Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String + } + + private static func getInfoValue(forKey key: String) -> Any? { + // Access the SDKInfo.plist using Bundle.module + guard let url = Bundle.module.url(forResource: "SDKInfo", withExtension: "plist"), + let data = try? Data(contentsOf: url), + let plist = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any] + else { + return nil + } + return plist[key] + } +} From 616cf2a82aa0bbcb143820ddea1c21355ac7934b Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 15:07:46 +0300 Subject: [PATCH 4/9] Add the headers --- Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift b/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift index 05f67f8d..aceb123f 100644 --- a/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift +++ b/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift @@ -14,6 +14,9 @@ struct URLSessionHTTPClient: HTTPClient { let configuration = URLSessionConfiguration.default configuration.httpAdditionalHeaders = [ "Accept": "application/json", + "X-Platform": "ios", + "X-SDK-Version": Info.sdkVersion ?? "", + "X-Source": Info.appName ?? "", ] self.urlSession = urlSession ?? URLSession(configuration: configuration) } From bf618c8db8241591f029d032ecefafad0c108699 Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 15:08:53 +0300 Subject: [PATCH 5/9] Rename --- Sources/Gravatar/{Info.swift => BundleInfo.swift} | 2 +- Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename Sources/Gravatar/{Info.swift => BundleInfo.swift} (97%) diff --git a/Sources/Gravatar/Info.swift b/Sources/Gravatar/BundleInfo.swift similarity index 97% rename from Sources/Gravatar/Info.swift rename to Sources/Gravatar/BundleInfo.swift index 8e19d864..39812e54 100644 --- a/Sources/Gravatar/Info.swift +++ b/Sources/Gravatar/BundleInfo.swift @@ -1,6 +1,6 @@ import Foundation -struct Info { +struct BundleInfo { public static var sdkVersion: String? { getInfoValue(forKey: "CFBundleShortVersionString") as? String } diff --git a/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift b/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift index aceb123f..8808c912 100644 --- a/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift +++ b/Sources/Gravatar/Network/Services/URLSessionHTTPClient.swift @@ -15,8 +15,8 @@ struct URLSessionHTTPClient: HTTPClient { configuration.httpAdditionalHeaders = [ "Accept": "application/json", "X-Platform": "ios", - "X-SDK-Version": Info.sdkVersion ?? "", - "X-Source": Info.appName ?? "", + "X-SDK-Version": BundleInfo.sdkVersion ?? "", + "X-Source": BundleInfo.appName ?? "", ] self.urlSession = urlSession ?? URLSession(configuration: configuration) } From e8804d93bdc938c3ff60f1f0e066665be0266fa6 Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 16:01:14 +0300 Subject: [PATCH 6/9] format --- Sources/Gravatar/BundleInfo.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Gravatar/BundleInfo.swift b/Sources/Gravatar/BundleInfo.swift index 39812e54..dc96d4c4 100644 --- a/Sources/Gravatar/BundleInfo.swift +++ b/Sources/Gravatar/BundleInfo.swift @@ -1,6 +1,6 @@ import Foundation -struct BundleInfo { +enum BundleInfo { public static var sdkVersion: String? { getInfoValue(forKey: "CFBundleShortVersionString") as? String } From 07fa931dd287d40dd8a07ac2e88d8d256b26d253 Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 16:05:53 +0300 Subject: [PATCH 7/9] Add resource_bundles to Gravatar.podspec --- Gravatar.podspec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gravatar.podspec b/Gravatar.podspec index 1d1b3367..03229947 100644 --- a/Gravatar.podspec +++ b/Gravatar.podspec @@ -23,6 +23,9 @@ Pod::Spec.new do |s| s.ios.deployment_target = ios_deployment_target s.source_files = 'Sources/Gravatar/**/*.swift' + s.resource_bundles = { + 'Gravatar' => ['Sources/Gravatar/Resources/*.plist'] + } # Using the `package` access level for types requires us to pass `-package-name` # as a swift flag, with the same name for each module/pod From d22794f320b009152740b2194da95b77b0afbe01 Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Thu, 3 Oct 2024 19:26:33 +0300 Subject: [PATCH 8/9] Add Bundle+ResourceBundle.swift --- Sources/Gravatar/Bundle+ResourceBundle.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Sources/Gravatar/Bundle+ResourceBundle.swift diff --git a/Sources/Gravatar/Bundle+ResourceBundle.swift b/Sources/Gravatar/Bundle+ResourceBundle.swift new file mode 100644 index 00000000..37dcade6 --- /dev/null +++ b/Sources/Gravatar/Bundle+ResourceBundle.swift @@ -0,0 +1,18 @@ +import Foundation + +#if !SWIFT_PACKAGE +private class BundleFinder: NSObject {} +extension Bundle { + static var module: Bundle { + let defaultBundle = Bundle(for: BundleFinder.self) + // If installed with CocoaPods, resources will be in GravatarUI.bundle + if let bundleURL = defaultBundle.resourceURL, + let resourceBundle = Bundle(url: bundleURL.appendingPathComponent("Gravatar.bundle")) + { + return resourceBundle + } + // Otherwise, the default bundle is used for resources + return defaultBundle + } +} +#endif From 2e1a915ceb7e05781c76c32a82725e0c9114e2cd Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Fri, 4 Oct 2024 10:29:15 +0300 Subject: [PATCH 9/9] Update code comment --- Sources/Gravatar/Bundle+ResourceBundle.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/Gravatar/Bundle+ResourceBundle.swift b/Sources/Gravatar/Bundle+ResourceBundle.swift index 37dcade6..0b49d969 100644 --- a/Sources/Gravatar/Bundle+ResourceBundle.swift +++ b/Sources/Gravatar/Bundle+ResourceBundle.swift @@ -5,7 +5,10 @@ private class BundleFinder: NSObject {} extension Bundle { static var module: Bundle { let defaultBundle = Bundle(for: BundleFinder.self) - // If installed with CocoaPods, resources will be in GravatarUI.bundle + // If installed with CocoaPods, resources will be in Gravatar.bundle + // The name of the bundle "Gravatar.bundle" (without the .bundle file extension) + // needs to match the key in the respective Gravatar.podspec: + // `s.resource_bundles = { 'Gravatar' => ['Sources/Gravatar/Resources/*.plist'] }` if let bundleURL = defaultBundle.resourceURL, let resourceBundle = Bundle(url: bundleURL.appendingPathComponent("Gravatar.bundle")) {