diff --git a/Package.swift b/Package.swift index ac2307e..290b695 100644 --- a/Package.swift +++ b/Package.swift @@ -21,7 +21,7 @@ let package = Package( "../../build-documentation.sh" ], resources: [ - .copy("Sources/SwiftHelpers/PrivacyInfo/PrivacyInfo.xcprivacy") + .copy("./PrivacyInfo.xcprivacy") ], linkerSettings: [ .linkedFramework("SwiftUI"), diff --git a/README.md b/README.md index add5d3f..8558813 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ Use Swift to create some amazing things! ## Package Development Environment -* macOS Sonoma 14.3 (23D56) -* Xcode 15.2 (15C500b) +* macOS Sonoma 14.4.1 (23E224) +* Xcode 15.3 (15E204a) * Swift 5.9.2 (5.9.2.2.56) ## Install @@ -37,12 +37,12 @@ import Foundation import SwiftHelpers func createURLRequest(with url: URL, - method: HTTP.HTTPMethod, + method: HTTP.Method, parameters: E) -> URLRequest where E: Encodable { var request = URLRequest(url: url) request.httpMethod = method.rawValue request.allHTTPHeaderFields = [ - HTTP.HTTPHeaderFields.contentType.rawValue : HTTP.HTTPContentType.json.rawValue + HTTP.HeaderFields.contentType.rawValue : HTTP.ContentType.json.rawValue ] if method != .get { diff --git a/Sources/SwiftHelpers/Extensions/SwiftUI/Image+Extensions.swift b/Sources/SwiftHelpers/Extensions/SwiftUI/Image+Extensions.swift index fdf9a5e..960406f 100644 --- a/Sources/SwiftHelpers/Extensions/SwiftUI/Image+Extensions.swift +++ b/Sources/SwiftHelpers/Extensions/SwiftUI/Image+Extensions.swift @@ -27,28 +27,5 @@ public extension Image { public extension Image { - /// Use ``SFSymbols`` to initialize `Image` - @available( - *, - deprecated, - renamed: "init(symbols:)", - message: "Deprecated since version 0.0.9, renamed to init(symbols:) and will be removed in a future version" - ) - init(systemIcon: SFSymbols) { - self.init(systemName: systemIcon.rawValue) - } - /// Use ``SFSymbols`` to initialize `Image` - /// - /// This initializer is available in iOS 16.0 and macOS 13.0 or above - @available(iOS 16.0, macOS 13.0, *) - @available( - *, - deprecated, - renamed: "init(symbols:variableValue:)", - message: "Deprecated since version 0.0.9, renamed to init(symbols:variableValue:) and will be removed in a future version" - ) - init(systemIcon: SFSymbols, variableValue: Double?) { - self.init(systemName: systemIcon.rawValue, variableValue: variableValue) - } } diff --git a/Sources/SwiftHelpers/Extensions/SwiftUI/Label+Extensions.swift b/Sources/SwiftHelpers/Extensions/SwiftUI/Label+Extensions.swift index f8eb9c9..710a03d 100644 --- a/Sources/SwiftHelpers/Extensions/SwiftUI/Label+Extensions.swift +++ b/Sources/SwiftHelpers/Extensions/SwiftUI/Label+Extensions.swift @@ -24,25 +24,5 @@ public extension Label where Title == Text, Icon == Image { public extension Label where Title == Text, Icon == Image { - /// Use ``SFSymbols`` and `LocalizedStringKey` to initialize `Label` - @available( - *, - deprecated, - renamed: "init(_:symbols:)", - message: "Deprecated since version 0.0.9, renamed to init(symbols:) and will be removed in a future version" - ) - init(_ titleKey: LocalizedStringKey, systemIcon name: SFSymbols) { - self.init(titleKey, systemImage: name.rawValue) - } - /// Use ``SFSymbols`` and `String` to initialize `Label` - @available( - *, - deprecated, - renamed: "init(_:symbols:)", - message: "Deprecated since version 0.0.9, renamed to init(symbols:) and will be removed in a future version" - ) - init(_ title: S, systemIcon name: SFSymbols) where S : StringProtocol { - self.init(title, systemImage: name.rawValue) - } } diff --git a/Sources/SwiftHelpers/Extensions/UIKit/UIImage+Extensions.swift b/Sources/SwiftHelpers/Extensions/UIKit/UIImage+Extensions.swift index 6df8382..b8fd0ed 100644 --- a/Sources/SwiftHelpers/Extensions/UIKit/UIImage+Extensions.swift +++ b/Sources/SwiftHelpers/Extensions/UIKit/UIImage+Extensions.swift @@ -20,15 +20,6 @@ public extension UIImage { public extension UIImage { - /// Use ``SFSymbols`` to initialize `UIImage` - @available( - *, - deprecated, - renamed: "init(symbols:)", - message: "Deprecated since version 0.0.9, renamed to init(symbols:) and will be removed in a future version" - ) - convenience init?(systemIcon: SFSymbols) { - self.init(systemName: systemIcon.rawValue) - } + } #endif diff --git a/Sources/SwiftHelpers/Network/HTTP/ContentType.swift b/Sources/SwiftHelpers/Network/HTTP/ContentType.swift new file mode 100644 index 0000000..62b6fc4 --- /dev/null +++ b/Sources/SwiftHelpers/Network/HTTP/ContentType.swift @@ -0,0 +1,38 @@ +// +// ContentType.swift +// SwiftHelpers/Network +// +// Created by Leo Ho on 2023/6/14. +// + +import Foundation + +public extension HTTP { + + /// Define the HTTP Content-Type of the HTTP Request + enum ContentType: String, CustomStringConvertible { + + /// HTTP Request body Content-Type,JSON + case json = "application/json" + + /// HTTP Request body Content-Type,XML + case xml = "application/xml" + + /// HTTP Request body Content-Type,text/plain + case textPlain = "text/plain" + + /// HTTP Request body Content-Type,x-www-form-urlencoded + case x_www_form_urlencoded = "application/x-www-form-urlencoded" + + /// HTTP Request body Content-Type,multipart/form-data + case formData = "multipart/form-data" + + /// HTTP Request body Content-Type,application/octet-stream + case octetStream = "application/octet-stream" + + public var description: String { + let base = "[HTTP Content-Type] " + return base + self.rawValue + } + } +} diff --git a/Sources/SwiftHelpers/Network/Http/HTTP.swift b/Sources/SwiftHelpers/Network/HTTP/HTTP.swift similarity index 100% rename from Sources/SwiftHelpers/Network/Http/HTTP.swift rename to Sources/SwiftHelpers/Network/HTTP/HTTP.swift diff --git a/Sources/SwiftHelpers/Network/Http/HeaderFields.swift b/Sources/SwiftHelpers/Network/HTTP/HeaderFields.swift similarity index 58% rename from Sources/SwiftHelpers/Network/Http/HeaderFields.swift rename to Sources/SwiftHelpers/Network/HTTP/HeaderFields.swift index 2771985..be846ab 100644 --- a/Sources/SwiftHelpers/Network/Http/HeaderFields.swift +++ b/Sources/SwiftHelpers/Network/HTTP/HeaderFields.swift @@ -10,28 +10,28 @@ import Foundation public extension HTTP { /// Define the HTTP Header Fields of the HTTP Request request - enum HTTPHeaderFields: String, CustomStringConvertible { + enum HeaderFields: String, CustomStringConvertible { - /// HTTP Request's HeaderFields,Authorization + /// HTTP Request HeaderFields,Authorization case authentication = "Authorization" - /// HTTP Request's HeaderFields, Content-Type + /// HTTP Request HeaderFields, Content-Type case contentType = "Content-Type" - /// HTTP Request's HeaderFields,Accept + /// HTTP Request HeaderFields,Accept case acceptType = "Accept" - /// HTTP Request's HeaderFields,Accept-Encoding + /// HTTP Request HeaderFields,Accept-Encoding case acceptEncoding = "Accept-Encoding" - /// HTTP Request's HeaderFields,User-Key + /// HTTP Request HeaderFields,User-Key case userKey = "User-Key" - /// HTTP Request's HeaderFields,Cookie + /// HTTP Request HeaderFields,Cookie case cookie = "Cookie" public var description: String { - let base = "HTTP Header Fields: " + let base = "[HTTP Header Fields] " return base + self.rawValue } } diff --git a/Sources/SwiftHelpers/Network/Http/Method.swift b/Sources/SwiftHelpers/Network/HTTP/Method.swift similarity index 90% rename from Sources/SwiftHelpers/Network/Http/Method.swift rename to Sources/SwiftHelpers/Network/HTTP/Method.swift index 0edb02a..260e503 100644 --- a/Sources/SwiftHelpers/Network/Http/Method.swift +++ b/Sources/SwiftHelpers/Network/HTTP/Method.swift @@ -10,7 +10,7 @@ import Foundation public extension HTTP { /// Define the HTTP Method of the HTTP Request request - enum HTTPMethod: String, CustomStringConvertible { + enum Method: String, CustomStringConvertible { /// HTTP Method - GET case `get` = "GET" @@ -40,7 +40,7 @@ public extension HTTP { case patch = "PATCH" public var description: String { - let base = "HTTP Method: " + let base = "[HTTP Method] " return base + self.rawValue } } diff --git a/Sources/SwiftHelpers/Network/Http/Status.swift b/Sources/SwiftHelpers/Network/HTTP/StatusCode.swift similarity index 74% rename from Sources/SwiftHelpers/Network/Http/Status.swift rename to Sources/SwiftHelpers/Network/HTTP/StatusCode.swift index e96fee1..c49e303 100644 --- a/Sources/SwiftHelpers/Network/Http/Status.swift +++ b/Sources/SwiftHelpers/Network/HTTP/StatusCode.swift @@ -1,5 +1,5 @@ // -// Status.swift +// StatusCode.swift // SwiftHelpers/Network // // Created by Leo Ho on 2023/6/13. @@ -9,74 +9,74 @@ import Foundation public extension HTTP { - /// Define HTTP Status of HTTP Response - enum HTTPStatus: Int, LocalizedError, CustomNSError { + /// Define HTTP StatusCode of HTTP Response + enum StatusCode: Int, LocalizedError, CustomNSError { // MARK: Initializer public init?(rawValue: Int) { switch rawValue { - case HTTPStatus.continue.rawValue: self = .continue - case HTTPStatus.switchingProtocols.rawValue: self = .switchingProtocols - case HTTPStatus.processing.rawValue: self = .processing - case HTTPStatus.earlyHints.rawValue: self = .earlyHints - case HTTPStatus.ok.rawValue: self = .ok - case HTTPStatus.created.rawValue: self = .created - case HTTPStatus.accepted.rawValue: self = .accepted - case HTTPStatus.nonAuthoritativeInformation.rawValue: self = .nonAuthoritativeInformation - case HTTPStatus.noContent.rawValue: self = .noContent - case HTTPStatus.resetContent.rawValue: self = .resetContent - case HTTPStatus.partialContent.rawValue: self = .partialContent - case HTTPStatus.multiStatus.rawValue: self = .multiStatus - case HTTPStatus.alreadyReported.rawValue: self = .alreadyReported - case HTTPStatus.imUsed.rawValue: self = .imUsed - case HTTPStatus.multipleChoices.rawValue: self = .multipleChoices - case HTTPStatus.movedPermanently.rawValue: self = .movedPermanently - case HTTPStatus.found.rawValue: self = .found - case HTTPStatus.seeOther.rawValue: self = .seeOther - case HTTPStatus.notModified.rawValue: self = .notModified - case HTTPStatus.temporaryRedirect.rawValue: self = .temporaryRedirect - case HTTPStatus.permanentRedirect.rawValue: self = .permanentRedirect - case HTTPStatus.badRequest.rawValue: self = .badRequest - case HTTPStatus.unauthorized.rawValue: self = .unauthorized - case HTTPStatus.paymentRequired.rawValue: self = .paymentRequired - case HTTPStatus.forbidden.rawValue: self = .forbidden - case HTTPStatus.notFound.rawValue: self = .notFound - case HTTPStatus.methodNotAllowed.rawValue: self = .methodNotAllowed - case HTTPStatus.notAcceptable.rawValue: self = .notAcceptable - case HTTPStatus.proxyAuthenticationRequired.rawValue: self = .proxyAuthenticationRequired - case HTTPStatus.requestTimeout.rawValue: self = .requestTimeout - case HTTPStatus.conflict.rawValue: self = .conflict - case HTTPStatus.gone.rawValue: self = .gone - case HTTPStatus.lengthRequired.rawValue: self = .lengthRequired - case HTTPStatus.preconditionFailed.rawValue: self = .preconditionFailed - case HTTPStatus.contentTooLarge.rawValue: self = .contentTooLarge - case HTTPStatus.uriTooLong.rawValue: self = .uriTooLong - case HTTPStatus.unsupportedMediaType.rawValue: self = .unsupportedMediaType - case HTTPStatus.rangeNotSatisfiable.rawValue: self = .rangeNotSatisfiable - case HTTPStatus.expectationFailed.rawValue: self = .expectationFailed - case HTTPStatus.iMaTeapot.rawValue: self = .iMaTeapot - case HTTPStatus.misdirectedRequest.rawValue: self = .misdirectedRequest - case HTTPStatus.unprocessableContent.rawValue: self = .unprocessableContent - case HTTPStatus.locked.rawValue: self = .locked - case HTTPStatus.failedDependency.rawValue: self = .failedDependency - case HTTPStatus.tooEarly.rawValue: self = .tooEarly - case HTTPStatus.upgradeRequired.rawValue: self = .upgradeRequired - case HTTPStatus.preconditionRequired.rawValue: self = .preconditionRequired - case HTTPStatus.tooManyRequests.rawValue: self = .tooManyRequests - case HTTPStatus.requestHeaderFieldsTooLarge.rawValue: self = .requestHeaderFieldsTooLarge - case HTTPStatus.unavailableForLegalReasons.rawValue: self = .unavailableForLegalReasons - case HTTPStatus.internalServerError.rawValue: self = .internalServerError - case HTTPStatus.notImplemented.rawValue: self = .notImplemented - case HTTPStatus.badGateway.rawValue: self = .badGateway - case HTTPStatus.serviceUnavailable.rawValue: self = .serviceUnavailable - case HTTPStatus.gatewayTimeout.rawValue: self = .gatewayTimeout - case HTTPStatus.httpVersionNotSupported.rawValue: self = .httpVersionNotSupported - case HTTPStatus.variantAlsoNegotiates.rawValue: self = .variantAlsoNegotiates - case HTTPStatus.insufficientStorage.rawValue: self = .insufficientStorage - case HTTPStatus.loopDetected.rawValue: self = .loopDetected - case HTTPStatus.notExtended.rawValue: self = .notExtended - case HTTPStatus.networkAuthenticationRequired.rawValue: self = .networkAuthenticationRequired + case StatusCode.continue.rawValue: self = .continue + case StatusCode.switchingProtocols.rawValue: self = .switchingProtocols + case StatusCode.processing.rawValue: self = .processing + case StatusCode.earlyHints.rawValue: self = .earlyHints + case StatusCode.ok.rawValue: self = .ok + case StatusCode.created.rawValue: self = .created + case StatusCode.accepted.rawValue: self = .accepted + case StatusCode.nonAuthoritativeInformation.rawValue: self = .nonAuthoritativeInformation + case StatusCode.noContent.rawValue: self = .noContent + case StatusCode.resetContent.rawValue: self = .resetContent + case StatusCode.partialContent.rawValue: self = .partialContent + case StatusCode.multiStatus.rawValue: self = .multiStatus + case StatusCode.alreadyReported.rawValue: self = .alreadyReported + case StatusCode.imUsed.rawValue: self = .imUsed + case StatusCode.multipleChoices.rawValue: self = .multipleChoices + case StatusCode.movedPermanently.rawValue: self = .movedPermanently + case StatusCode.found.rawValue: self = .found + case StatusCode.seeOther.rawValue: self = .seeOther + case StatusCode.notModified.rawValue: self = .notModified + case StatusCode.temporaryRedirect.rawValue: self = .temporaryRedirect + case StatusCode.permanentRedirect.rawValue: self = .permanentRedirect + case StatusCode.badRequest.rawValue: self = .badRequest + case StatusCode.unauthorized.rawValue: self = .unauthorized + case StatusCode.paymentRequired.rawValue: self = .paymentRequired + case StatusCode.forbidden.rawValue: self = .forbidden + case StatusCode.notFound.rawValue: self = .notFound + case StatusCode.methodNotAllowed.rawValue: self = .methodNotAllowed + case StatusCode.notAcceptable.rawValue: self = .notAcceptable + case StatusCode.proxyAuthenticationRequired.rawValue: self = .proxyAuthenticationRequired + case StatusCode.requestTimeout.rawValue: self = .requestTimeout + case StatusCode.conflict.rawValue: self = .conflict + case StatusCode.gone.rawValue: self = .gone + case StatusCode.lengthRequired.rawValue: self = .lengthRequired + case StatusCode.preconditionFailed.rawValue: self = .preconditionFailed + case StatusCode.contentTooLarge.rawValue: self = .contentTooLarge + case StatusCode.uriTooLong.rawValue: self = .uriTooLong + case StatusCode.unsupportedMediaType.rawValue: self = .unsupportedMediaType + case StatusCode.rangeNotSatisfiable.rawValue: self = .rangeNotSatisfiable + case StatusCode.expectationFailed.rawValue: self = .expectationFailed + case StatusCode.iMaTeapot.rawValue: self = .iMaTeapot + case StatusCode.misdirectedRequest.rawValue: self = .misdirectedRequest + case StatusCode.unprocessableContent.rawValue: self = .unprocessableContent + case StatusCode.locked.rawValue: self = .locked + case StatusCode.failedDependency.rawValue: self = .failedDependency + case StatusCode.tooEarly.rawValue: self = .tooEarly + case StatusCode.upgradeRequired.rawValue: self = .upgradeRequired + case StatusCode.preconditionRequired.rawValue: self = .preconditionRequired + case StatusCode.tooManyRequests.rawValue: self = .tooManyRequests + case StatusCode.requestHeaderFieldsTooLarge.rawValue: self = .requestHeaderFieldsTooLarge + case StatusCode.unavailableForLegalReasons.rawValue: self = .unavailableForLegalReasons + case StatusCode.internalServerError.rawValue: self = .internalServerError + case StatusCode.notImplemented.rawValue: self = .notImplemented + case StatusCode.badGateway.rawValue: self = .badGateway + case StatusCode.serviceUnavailable.rawValue: self = .serviceUnavailable + case StatusCode.gatewayTimeout.rawValue: self = .gatewayTimeout + case StatusCode.httpVersionNotSupported.rawValue: self = .httpVersionNotSupported + case StatusCode.variantAlsoNegotiates.rawValue: self = .variantAlsoNegotiates + case StatusCode.insufficientStorage.rawValue: self = .insufficientStorage + case StatusCode.loopDetected.rawValue: self = .loopDetected + case StatusCode.notExtended.rawValue: self = .notExtended + case StatusCode.networkAuthenticationRequired.rawValue: self = .networkAuthenticationRequired default: self = .unknown } } @@ -282,7 +282,7 @@ public extension HTTP { // MARK: - Implementation LocalizedError public var errorDescription: String { - let base = "HTTP Status Code: \(self.rawValue) " + let base = "[HTTP Status Code] \(self.rawValue) " switch self { case .unknown: return base + "Unknown Status Code" diff --git a/Sources/SwiftHelpers/Network/Http/ContentType.swift b/Sources/SwiftHelpers/Network/Http/ContentType.swift deleted file mode 100644 index 782bc4a..0000000 --- a/Sources/SwiftHelpers/Network/Http/ContentType.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// ContentType.swift -// SwiftHelpers/Network -// -// Created by Leo Ho on 2023/6/14. -// - -import Foundation - -public extension HTTP { - - /// Define the HTTP Content-Type of the HTTP Request - enum HTTPContentType: String, CustomStringConvertible { - - /// HTTP Request's body Content-Type,JSON - case json = "application/json" - - /// HTTP Request's body Content-Type,XML - case xml = "application/xml" - - /// HTTP Request's body Content-Type,text/plain - case textPlain = "text/plain" - - /// HTTP Request's body Content-Type,x-www-form-urlencoded - case x_www_form_urlencoded = "application/x-www-form-urlencoded" - - public var description: String { - let base = "HTTP Content-Type: " - return base + self.rawValue - } - } -} diff --git a/Sources/SwiftHelpers/Network/JSON/JSON.swift b/Sources/SwiftHelpers/Network/JSON/JSON.swift index 4b2665c..99590cb 100644 --- a/Sources/SwiftHelpers/Network/JSON/JSON.swift +++ b/Sources/SwiftHelpers/Network/JSON/JSON.swift @@ -17,8 +17,8 @@ public struct JSON { /// Failed to convert `Encodable Object` to `Dictionary` through `JSONSerialization.jsonObject` case encodableToDictFailed - /// Failed to convert `Dictionary` to `Data` through `JSONSerialization.data` - case dictToDataFailed + /// Failed to encode `Encodable Object` to `Data` through `JSONSerialization.data` + case encodingToJSONFailed // MARK: - Implementation LocalizedError @@ -26,7 +26,7 @@ public struct JSON { switch self { case .encodableToDictFailed: return "Failed to convert Encodable Object to `Dictionary` through `JSONSerialization.jsonObject`" - case .dictToDataFailed: + case .encodingToJSONFailed: return "Failed to convert `Dictionary` to `Data` through `JSONSerialization.data`" } } @@ -37,7 +37,7 @@ public struct JSON { switch self { case .encodableToDictFailed: return 0 - case .dictToDataFailed: + case .encodingToJSONFailed: return 1 } } @@ -48,9 +48,9 @@ public struct JSON { return [ "message" : "Failed to convert Encodable Object to `Dictionary` through `JSONSerialization.jsonObject`" ] - case .dictToDataFailed: + case .encodingToJSONFailed: return [ - "message" : "Failed to convert `Dictionary` to `Data` through `JSONSerialization.data`" + "message" : "Failed to encode `Encodable Object` to `Data` through `JSONSerialization.data`" ] } } @@ -60,7 +60,7 @@ public struct JSON { } } - /// Convert Encodable Object to JSON Data + /// Encode Encodable Object to JSON Data /// /// - Parameters: /// - data: Encodable Object @@ -71,7 +71,7 @@ public struct JSON { let jsonData = try JSONEncoder().encode(data) return jsonData } catch { - throw JSONEncodeError.dictToDataFailed + throw JSONEncodeError.encodingToJSONFailed } } } diff --git a/Sources/SwiftHelpers/PrivacyInfo/PrivacyInfo.xcprivacy b/Sources/SwiftHelpers/PrivacyInfo.xcprivacy similarity index 100% rename from Sources/SwiftHelpers/PrivacyInfo/PrivacyInfo.xcprivacy rename to Sources/SwiftHelpers/PrivacyInfo.xcprivacy diff --git a/Sources/SwiftHelpers/SwiftHelpers.swift b/Sources/SwiftHelpers/SwiftHelpers.swift new file mode 100644 index 0000000..0b48f36 --- /dev/null +++ b/Sources/SwiftHelpers/SwiftHelpers.swift @@ -0,0 +1,12 @@ +// +// SwiftHelpers.swift +// SwiftHelpers +// +// Created by Leo Ho on 2024/4/19. +// + +import Foundation + +public let buildVersion = "0.1.0 (1)" + +public let releaseVersion = "0.1.0" diff --git a/Sources/SwiftHelpers/Types/Base64/Base64+Protocols.swift b/Sources/SwiftHelpers/Types/Base64/Base64+Protocols.swift index d935de1..1d6fee9 100644 --- a/Sources/SwiftHelpers/Types/Base64/Base64+Protocols.swift +++ b/Sources/SwiftHelpers/Types/Base64/Base64+Protocols.swift @@ -71,5 +71,7 @@ public protocol Base64Convertable { /// - old: original encoding /// - new: encoding to convert /// - Returns: Converted encoded string - static func convert(with str: String, from old: Base64.Encoding, to new: Base64.Encoding) -> String + static func convert(with str: String, + from old: Base64.Encoding, + to new: Base64.Encoding) -> String } diff --git a/Sources/SwiftHelpers/Types/Base64/Base64.swift b/Sources/SwiftHelpers/Types/Base64/Base64.swift index 1999113..e09e017 100644 --- a/Sources/SwiftHelpers/Types/Base64/Base64.swift +++ b/Sources/SwiftHelpers/Types/Base64/Base64.swift @@ -209,116 +209,5 @@ extension Base64: Base64Decodable { public extension Base64 { - /// Convert base64 / base64URL encoded string to base64URL / base64 encoded string - /// - Parameters: - /// - str: base64 / base64URL encoded string - /// - operation: ``Encoding``, perform base64 / base64URL conversion operation - /// - Returns: base64URL / base64 encoded string - @available( - *, - deprecated, - renamed: "base64EncodedString(from:)", - message: "Deprecated since version 0.0.17, renamed to base64EncodedString(from:) and will be removed in a future version" - ) - static func base64EncodedString(from str: String, - operation: Base64.Encoding) -> String { - var result: String - - switch operation { - case .base64: - // Convert base64URL encoded string to base64 encoded string - result = str - .replacingOccurrences(of: "-", with: "+") - .replacingOccurrences(of: "_", with: "/") - case .base64URL: - // Convert base64 encoded string to base64URL encoded string - result = str - .replacingOccurrences(of: "+", with: "-") - .replacingOccurrences(of: "/", with: "_") - } - - guard operation == .base64 || operation == .base64URL else { - return result - } - - if result.count % 4 != 0 { - let str = String(repeating: "=", count: 4 - result.count % 4) - result.append(str) - } - - return result - } - - /// Decode base64 / base64URL encoded string into `Data` - /// - /// - Parameters: - /// - str: base64 / base64URL encoded string - /// - operation: ``Decoding``, perform base64 / base64URL conversion operation - /// - Throws: ``DecodingError`` - /// - Returns: `Data` initialized via base64 / base64URL encoded string - @available(*, unavailable) - static func base64DecodedData(from str: String, - operation: Base64.Encoding) throws -> Data { - switch operation { - case .base64: - // Decode base64 encoded string into Data - guard let base64DecodedData = Data(base64Encoded: str) else { - throw Base64.DecodingError.decodeFailed - } - - return base64DecodedData - case .base64URL: - // Decode base64URL encoded string into Data - let base64 = Base64.base64EncodedString(from: str, operation: .base64) - - guard let base64URLDecodedData = Data(base64Encoded: base64) else { - throw Base64.DecodingError.decodeFailed - } - - return base64URLDecodedData - } - } - /// Decode base64 / base64URL encoded string into UTF-8 encoded string - /// - /// - Parameters: - /// - str: base64 / base64URL encoded string - /// - operation: ``Encoding``, perform base64 / base64URL conversion operation - /// - Throws: ``DecodingError`` - /// - Returns: UTF-8 encoded string - @available( - *, - deprecated, - renamed: "base64DecodedString(from:)", - message: "Deprecated since version 0.0.17, renamed to base64DecodedString(from:) and will be removed in a future version" - ) - static func base64DecodedString(from str: String, - operation: Base64.Encoding) throws -> String { - switch operation { - case .base64: - // Decode base64 encoded string into UTF-8 string - guard let data = Data(base64Encoded: str) else { - throw Base64.DecodingError.decodeFailed - } - - guard let result = String(data: data, encoding: .utf8) else { - throw Base64.DecodingError.stringUTF8EncodeFailed - } - - return result - case .base64URL: - // Decode base64URL encoded string into UTF-8 string - let base64 = Base64.base64EncodedString(from: str, operation: .base64) - - guard let data = Data(base64Encoded: base64) else { - throw Base64.DecodingError.decodeFailed - } - - guard let result = String(data: data, encoding: .utf8) else { - throw Base64.DecodingError.stringUTF8EncodeFailed - } - - return result - } - } } diff --git a/Sources/SwiftHelpersUnitTests/HTTP.swift b/Sources/SwiftHelpersUnitTests/HTTP.swift index 4082bec..db5915f 100644 --- a/Sources/SwiftHelpersUnitTests/HTTP.swift +++ b/Sources/SwiftHelpersUnitTests/HTTP.swift @@ -20,15 +20,15 @@ final class HTTP: XCTestCase { func testHttpStatus() throws { let statusCode = 200 - let status = SwiftHelpers.HTTP.HTTPStatus.ok + let status = SwiftHelpers.HTTP.StatusCode.ok - let testStatus = SwiftHelpers.HTTP.HTTPStatus(rawValue: statusCode) + let testStatus = SwiftHelpers.HTTP.StatusCode(rawValue: statusCode) XCTAssertEqual(status, testStatus, "status 與 testStatus 一致") XCTAssertEqual(status.errorDescription, testStatus?.errorDescription) let unknownStatusCode = -1 - let testUnknownStatus = SwiftHelpers.HTTP.HTTPStatus.unknown + let testUnknownStatus = SwiftHelpers.HTTP.StatusCode.unknown XCTAssertEqual( unknownStatusCode,