diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index cda61a2..13dc401 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -18,5 +18,3 @@ jobs: - uses: actions/checkout@v3 - name: Build run: swift build -v - - name: Run tests - run: swift test -v diff --git a/.swiftpm/xcode/package.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate b/.swiftpm/xcode/package.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate index e6bcb51..d5733c8 100644 Binary files a/.swiftpm/xcode/package.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate and b/.swiftpm/xcode/package.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/BuildRequestTests.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/BuildRequestTests.xcscheme deleted file mode 100644 index 3ad5461..0000000 --- a/.swiftpm/xcode/xcshareddata/xcschemes/BuildRequestTests.xcscheme +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Networking-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Networking-Package.xcscheme new file mode 100644 index 0000000..8077c87 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/Networking-Package.xcscheme @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.swiftpm/xcode/xcuserdata/phongnd.xcuserdatad/xcschemes/xcschememanagement.plist b/.swiftpm/xcode/xcuserdata/phongnd.xcuserdatad/xcschemes/xcschememanagement.plist index 3da235f..c03bcb8 100644 --- a/.swiftpm/xcode/xcuserdata/phongnd.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/.swiftpm/xcode/xcuserdata/phongnd.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,25 +4,20 @@ SchemeUserState - BuildRequestTests.xcscheme_^#shared#^_ - - orderHint - 0 - CombineRequest.xcscheme_^#shared#^_ orderHint - 7 + 1 CombineSocketIO.xcscheme_^#shared#^_ orderHint - 3 + 2 CombineWebSocket.xcscheme_^#shared#^_ orderHint - 10 + 3 Networking-Package.xcscheme_^#shared#^_ @@ -34,21 +29,21 @@ isShown orderHint - 12 + 17 ReactiveSwift (Playground) 2.xcscheme isShown orderHint - 13 + 18 ReactiveSwift (Playground).xcscheme isShown orderHint - 11 + 13 ReactiveSwift-UIExamples (Playground) 1.xcscheme @@ -74,53 +69,106 @@ ReactiveSwiftRequest.xcscheme_^#shared#^_ orderHint - 6 + 4 ReactiveSwiftSocketIO.xcscheme_^#shared#^_ orderHint - 2 + 5 ReactiveSwiftWebSocket.xcscheme_^#shared#^_ orderHint - 8 + 6 Rx (Playground) 1.xcscheme isShown orderHint - 18 + 11 Rx (Playground) 2.xcscheme isShown orderHint - 19 + 12 Rx (Playground).xcscheme isShown orderHint - 17 + 10 RxSwiftRequest.xcscheme_^#shared#^_ orderHint - 9 + 7 RxSwiftSocketIO.xcscheme_^#shared#^_ orderHint - 4 + 8 RxSwiftWebSocket.xcscheme_^#shared#^_ orderHint - 5 + 9 + + + SuppressBuildableAutocreation + + BuildRequestTests + + primary + + + CombineRequest + + primary + + + CombineSocketIO + + primary + + + CombineWebSocket + + primary + + + ReactiveSwiftRequest + + primary + + + ReactiveSwiftSocketIO + + primary + + + ReactiveSwiftWebSocket + + primary + + + RxSwiftRequest + + primary + + + RxSwiftSocketIO + + primary + + + RxSwiftWebSocket + + primary + diff --git a/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 0ec9b89..0b4e965 100644 --- a/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/Alamofire/Alamofire.git", "state": { "branch": null, - "revision": "78424be314842833c04bc3bef5b72e85fff99204", - "version": "5.6.4" + "revision": "b2fa556e4e48cbf06cf8c63def138c98f4b811fa", + "version": "5.8.0" } }, { @@ -33,8 +33,8 @@ "repositoryURL": "https://github.com/ReactiveX/RxSwift.git", "state": { "branch": null, - "revision": "b4307ba0b6425c0ba4178e138799946c3da594f8", - "version": "6.5.0" + "revision": "9dcaa4b333db437b0fbfaf453fad29069044a8b4", + "version": "6.6.0" } }, { diff --git a/Examples/Examples.xcodeproj/project.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate b/Examples/Examples.xcodeproj/project.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate index d6f79e5..792edfb 100644 Binary files a/Examples/Examples.xcodeproj/project.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate and b/Examples/Examples.xcodeproj/project.xcworkspace/xcuserdata/phongnd.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Examples/Examples/ContentView.swift b/Examples/Examples/ContentView.swift index b48a7c1..ab517c9 100644 --- a/Examples/Examples/ContentView.swift +++ b/Examples/Examples/ContentView.swift @@ -29,7 +29,7 @@ extension ContentView { Task { do { let request = MRequest { - RUrl(urlString: "https://api.publicapis.org/categories") + RUrl("https://api.publicapis.org/categories") } .printCURLRequest() .cURLDescription { curl in diff --git a/Examples/Examples/ExamplesApp.swift b/Examples/Examples/ExamplesApp.swift index e8339f6..047c747 100644 --- a/Examples/Examples/ExamplesApp.swift +++ b/Examples/Examples/ExamplesApp.swift @@ -10,7 +10,7 @@ struct ExamplesApp: App { .task { Task { let data = try await MRequest { - RUrl(urlString: "http://127.0.0.1:8080") + RUrl("http://127.0.0.1:8080") .withPath("todos") Rbody(Todo(id: UUID(), text: "_text", isCompleted: false).toData()) RMethod(.post) diff --git a/Examples/Examples/NetworkService/AuthService.swift b/Examples/Examples/NetworkService/AuthService.swift index 4ce0b98..be24a80 100644 --- a/Examples/Examples/NetworkService/AuthService.swift +++ b/Examples/Examples/NetworkService/AuthService.swift @@ -6,10 +6,10 @@ public class AuthService: BaseService { func login(email: String, password: String) -> MRequest { MRequest { - RUrl(urlString: urlString) + RUrl(urlString) .withPath("v1") .withPath("login") - RHeaders(headers: noAuthHeader) + RHeaders(noAuthHeader) RMethod(.post) Rbody(["email": email, "password": password].toData()) } @@ -17,10 +17,10 @@ public class AuthService: BaseService { func register(email: String, password: String) -> MRequest { MRequest { - RUrl(urlString: urlString) + RUrl(urlString) .withPath("v1") .withPath("register") - RHeaders(headers: noAuthHeader) + RHeaders(noAuthHeader) RMethod(.post) Rbody(["email": email, "password": password].toData()) } diff --git a/Package.resolved b/Package.resolved index 6f7363b..6b0ab50 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/Alamofire/Alamofire.git", "state": { "branch": null, - "revision": "78424be314842833c04bc3bef5b72e85fff99204", - "version": "5.6.4" + "revision": "b2fa556e4e48cbf06cf8c63def138c98f4b811fa", + "version": "5.8.0" } }, { @@ -24,8 +24,8 @@ "repositoryURL": "https://github.com/ReactiveX/RxSwift.git", "state": { "branch": null, - "revision": "b4307ba0b6425c0ba4178e138799946c3da594f8", - "version": "6.5.0" + "revision": "9dcaa4b333db437b0fbfaf453fad29069044a8b4", + "version": "6.6.0" } }, { diff --git a/Package.swift b/Package.swift index 3494fa5..9f0ccac 100644 --- a/Package.swift +++ b/Package.swift @@ -44,11 +44,11 @@ let package = Package( targets: ["MSocketIO", "MReactiveSwiftSocketIO"]), ], dependencies: [ - .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.6.4"), + .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.8.0"), .package(url: "https://github.com/daltoniam/Starscream.git", from: "4.0.4"), - .package(url: "https://github.com/ReactiveX/RxSwift.git", from: "6.5.0"), - .package(url: "https://github.com/ReactiveCocoa/ReactiveSwift.git", from: "7.0.0"), .package(name: "SocketIO", url: "https://github.com/socketio/socket.io-client-swift",from: "16.0.1"), + .package(url: "https://github.com/ReactiveX/RxSwift.git", from: "6.6.0"), + .package(url: "https://github.com/ReactiveCocoa/ReactiveSwift.git", from: "7.1.1"), ], targets: [ /** @@ -129,12 +129,12 @@ let package = Package( dependencies: ["MSocketIO", "ReactiveSwift"], path: "Sources/MSocketIO/MSocketIOReactiveSwift" ), - .testTarget( - name: "BuildRequestTests", - dependencies: [ - "BuildRequest" - ] - ) +// .testTarget( +// name: "BuildRequestTests", +// dependencies: [ +// "BuildRequest" +// ] +// ) /** diff --git a/README.md b/README.md index 04e0d04..6dcbc81 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,26 @@ ```swift let urlString = "https://httpbin.org/get" let request = MRequest { + RUrl(urlString) + RPath(path) + Rbody(data) + REncoding(JSONEncoding.default) RMethod(.get) - RUrl(urlString: urlString) + RHeaders() + RQueryItem() + RQueryItems() /// somthing else } let socket = MSocket { - RUrl(urlString: urlString) + RUrl(urlString) + RPath(path) + Rbody(data) + REncoding(JSONEncoding.default) + RMethod(.get) + RHeaders() + RQueryItem() + RQueryItems() /// somthing else } @@ -21,6 +34,27 @@ socketIO.on("event") ``` ### Response Handling +- Async +```swift +/// Data +let data = try await request.data + +/// String +let string = try await request.string + +/// Result +let result = await request.resultData + +/// Result +let result = await request.resultString + +/// DataTask +let data = await request.serializingData + +/// DataTask +let string = await request.serializingString +``` + - Combine ```swift request.sink { response in @@ -63,6 +97,21 @@ socketIO.on("event").subscribe { dict in debugPrint(dict) } ``` + +- CURL +```swift +let request: = ... +request +.printCURLRequest() // -> Self + + +request +.cURLDescription { curl in + // Todo with curl +} // -> Self + +``` + ## Installation ### Swift Package Manager diff --git a/Sources/BuildRequest/Core/RequestProtocol.swift b/Sources/BuildRequest/Core/RequestProtocol.swift index 7d6671d..ec993af 100644 --- a/Sources/BuildRequest/Core/RequestProtocol.swift +++ b/Sources/BuildRequest/Core/RequestProtocol.swift @@ -6,20 +6,108 @@ public protocol RequestProtocol: CustomStringConvertible, CustomDebugStringConve extension RequestProtocol { - public func build(request: URLRequest) { - + /// Description + /// - Parameter mutation: mutation your Request + /// - Returns: Self + public func with(_ mutation: (inout Self) -> Void) -> Self { + var this = self + mutation(&this) + return this + } + + /// Applies the given transform if the given condition evaluates to `true`. + /// - Parameters: + /// - condition: The condition to evaluate. + /// - transform: The transform to apply to the source `RequestProtocol`. + /// - Returns: Either the original `RequestProtocol` or the modified `RequestProtocol` if the condition is `true`. + @RequestBuilder + public func `if`( + _ condition: Bool, @RequestBuilder transform: (Self) -> Transform + ) -> any RequestProtocol { + if condition { + transform(self) + .eraseToRAny() + } else { + self + .eraseToRAny() + } + } + + + /// Applies the given transform `transform` or `else`. + /// - Parameters: + /// - condition: The condition to evaluate. + /// - transform: The transform to apply to the source `RequestProtocol`. + /// - else: The transform that applies if `condition` is false + /// - Returns: Either the original `RequestProtocol` or the modified `RequestProtocol` based on the condition`. + @RequestBuilder + public func `if`( + _ condition: Bool, transform: (Self) -> Content, + @RequestBuilder else: (Self) -> Content + ) -> any RequestProtocol { + if condition { + transform(self) + .eraseToRAny() + } else { + `else`(self) + .eraseToRAny() + } + } + + /// Unwraps the given `value` and applies the given `transform`. + /// - Parameters: + /// - value: The value to unwrap. + /// - transform: The transform to apply to the source `RequestProtocol`. + /// - Returns: Either the original `RequestProtocol` or the modified `RequestProtocol` with unwrapped `value` if the `value` is not nil`. + @RequestBuilder + public func ifLet( + _ value: Value?, + @RequestBuilder transform: (Value, Self) -> Content + ) -> any RequestProtocol { + if let value = value { + transform(value, self) + .eraseToRAny() + } else { + self + .eraseToRAny() + } } - public func executing( - request: inout URLRequest, - requests: [RequestProtocol] - ) { + /// Unwraps the given `value` and applies the given `transform`. + /// - Parameters: + /// - value: The value to unwrap. + /// - transform: The transform to apply to the source `RequestProtocol`. + /// - else:The transform that applies if `value` is nil + /// - Returns: Either the `else` transform or the modified `RequestProtocol` with unwrapped `value` if the `value` is not nil`. + @RequestBuilder + public func ifLet( + _ value: Value?, + @RequestBuilder transform: (Value, Self) -> Content, + @RequestBuilder else: (Self) -> Content + ) -> any RequestProtocol { + if let value = value { + transform(value, self) + .eraseToRAny() + } else { + `else`(self) + .eraseToRAny() + } + } +} + +extension RequestProtocol { + + public func build(request: URLRequest) { } + + public func executing(request: inout URLRequest, requests: [RequestProtocol] = []) { if requests.isEmpty { return } - var items: [RequestProtocol] = [] - items.append(contentsOf: requests.filter({$0 is RUrl})) - items.append(contentsOf: requests.filter({$0 is RPath})) - items.append(contentsOf: requests.filter({!($0 is RUrl || $0 is REncoding || $0 is RPath)})) - items.append(contentsOf: requests.filter({$0 is REncoding})) +// var items: [RequestProtocol] = [] +// items.append(contentsOf: requests.filter({$0 is RUrl})) +// items.append(contentsOf: requests.filter({$0 is RPath})) +// items.append(contentsOf: requests.filter({!($0 is RUrl || $0 is REncoding || $0 is RPath)})) +// items.append(contentsOf: requests.filter({$0 is REncoding})) + + let items: [RequestProtocol] = requests.cRequests() /// build items.forEach { $0.build(request: &request) @@ -42,3 +130,63 @@ extension RequestProtocol { description } } + +extension Array where Element == any RequestProtocol { + var rUrl: [Element] { + requests(RUrl.self) + } + + var rPath: [Element] { + requests(RPath.self) + } + + var rBody: [Element] { + requests(Rbody.self) + } + + var rMethod: [Element] { + requests(RMethod.self) + } + + var rEncoding: [Element] { + requests(REncoding.self) + } + + var rHeader: [Element] { + requests(RHeaders.self) + } + + var rQueryItem: [Element] { + requests(RQueryItem.self) + } + + var rQueryItems: [Element] { + requests(RQueryItems.self) + } + + var rOther: [Element] { + self.remove { + $0.is(RUrl.self) || $0.is(RPath.self) || + $0.is(RMethod.self) || $0.is(Rbody.self) || + $0.is(REncoding.self) || $0.is(RHeaders.self) || + $0.is(RQueryItem.self) || $0.is(RQueryItems.self) || + $0.is(REncoding.self) + } + } + + func cRequests() -> [RequestProtocol] { + rUrl + rPath + rBody + rMethod + rHeader + rQueryItem + rQueryItems + rEncoding + rOther + } + + func requests(_ type: R.Type) -> [Element] { + self.filter({$0.is(R.self)}) + } + + func remove(ifTrue: (Element) -> Bool) -> Self { + var clone = self + clone.removeAll { + ifTrue($0) + } + return clone + } +} diff --git a/Sources/BuildRequest/RequestBuilds/RAny.swift b/Sources/BuildRequest/RequestBuilds/RAny.swift new file mode 100644 index 0000000..f9ce3a9 --- /dev/null +++ b/Sources/BuildRequest/RequestBuilds/RAny.swift @@ -0,0 +1,44 @@ +import Foundation + +public struct RAny: RequestProtocol { + + let request: any RequestProtocol + + public init(_ request: any RequestProtocol) { + self.request = request + } + + public func build(request: inout URLRequest) { + self.request.build(request: &request) + } + + public func `as`(_ type: R.Type) -> R? { + self.request as? R + } + + public func `is`(_ type: R.Type) -> Bool { + return (request is R) + } +} + +extension RequestProtocol { + public func eraseToRAny() -> RAny { + RAny(self) + } + + public func `as`(_ type: R.Type) -> R? { + if let rAny = self as? RAny { + return rAny.as(type) + } else { + return self as? R + } + } + + public func `is`(_ type: R.Type) -> Bool { + if let rAny = self as? RAny { + return rAny.is(type) + } else { + return (self is R) + } + } +} diff --git a/Sources/BuildRequest/RequestBuilds/REncoding.swift b/Sources/BuildRequest/RequestBuilds/REncoding.swift index a5a2a90..aab097a 100644 --- a/Sources/BuildRequest/RequestBuilds/REncoding.swift +++ b/Sources/BuildRequest/RequestBuilds/REncoding.swift @@ -2,7 +2,7 @@ import Foundation import Alamofire public struct REncoding: RequestProtocol { - private let encoding: ParameterEncoding + private let encoding: any ParameterEncoding public init(_ encoding: ParameterEncoding = URLEncoding.default) { self.encoding = encoding @@ -16,6 +16,12 @@ public struct REncoding: RequestProtocol { } } +extension REncoding { + public init(_ initial: () -> any ParameterEncoding) { + self.init(initial()) + } +} + extension REncoding { public var description: String { [typeName: encoding.typeName].description diff --git a/Sources/BuildRequest/RequestBuilds/RHeaders.swift b/Sources/BuildRequest/RequestBuilds/RHeaders.swift index dfca924..e830ea7 100644 --- a/Sources/BuildRequest/RequestBuilds/RHeaders.swift +++ b/Sources/BuildRequest/RequestBuilds/RHeaders.swift @@ -3,7 +3,7 @@ import Foundation public struct RHeaders: RequestProtocol { private let headers: HTTPHeaders - public init(headers: HTTPHeaders) { + public init(_ headers: HTTPHeaders) { self.headers = headers } @@ -12,6 +12,12 @@ public struct RHeaders: RequestProtocol { } } +extension RHeaders { + public init(_ initial: () -> HTTPHeaders) { + self.init(initial()) + } +} + extension RHeaders { public var description: String { [typeName: headers.dictionary.toString() ?? "nil"].description diff --git a/Sources/BuildRequest/RequestBuilds/RMethod.swift b/Sources/BuildRequest/RequestBuilds/RMethod.swift index 2e92c1c..c398ea9 100644 --- a/Sources/BuildRequest/RequestBuilds/RMethod.swift +++ b/Sources/BuildRequest/RequestBuilds/RMethod.swift @@ -12,6 +12,12 @@ public struct RMethod: RequestProtocol { } } +extension RMethod { + public init(_ initial: () -> HTTPMethod) { + self.init(initial()) + } +} + extension RMethod { public var description: String { [typeName: httpMethod?.rawValue ?? "nil"].description diff --git a/Sources/BuildRequest/RequestBuilds/RPath.swift b/Sources/BuildRequest/RequestBuilds/RPath.swift index 94f0d23..fd373f8 100644 --- a/Sources/BuildRequest/RequestBuilds/RPath.swift +++ b/Sources/BuildRequest/RequestBuilds/RPath.swift @@ -3,7 +3,7 @@ import Foundation public struct RPath: RequestProtocol { private let path: String? - public init(path: String?) { + public init(_ path: String?) { self.path = path } @@ -23,6 +23,13 @@ public struct RPath: RequestProtocol { } } +extension RPath { + public init(_ initial: () -> String?) { + self.init(initial()) + } +} + + extension RPath { public var description: String { [typeName: path ?? "nil"].description diff --git a/Sources/BuildRequest/RequestBuilds/RQueryItem.swift b/Sources/BuildRequest/RequestBuilds/RQueryItem.swift index 5094c04..e910e21 100644 --- a/Sources/BuildRequest/RequestBuilds/RQueryItem.swift +++ b/Sources/BuildRequest/RequestBuilds/RQueryItem.swift @@ -20,6 +20,20 @@ public struct RQueryItem: RequestProtocol { } } +extension RQueryItem { + public init(_ key: () -> String, _ value: () -> String) { + self.init(key(), value: value()) + } + + public init(_ key: String, _ value: () -> String) { + self.init(key, value: value()) + } + + public init(_ key: () -> String, value: String) { + self.init(key(), value: value) + } +} + extension RQueryItem { var urlQueryItem: URLQueryItem { URLQueryItem(name: key, value: value) diff --git a/Sources/BuildRequest/RequestBuilds/RQueryItems.swift b/Sources/BuildRequest/RequestBuilds/RQueryItems.swift index 771727d..765f270 100644 --- a/Sources/BuildRequest/RequestBuilds/RQueryItems.swift +++ b/Sources/BuildRequest/RequestBuilds/RQueryItems.swift @@ -25,6 +25,12 @@ public struct RQueryItems: RequestProtocol { } } +extension RQueryItems { + public init(_ initial: () -> [String: Any]?) { + self.init(initial()) + } +} + extension RQueryItems { var urlQueryItems: [URLQueryItem] { children.map { $0.urlQueryItem } diff --git a/Sources/BuildRequest/RequestBuilds/RUrl.swift b/Sources/BuildRequest/RequestBuilds/RUrl.swift index 227ad3d..7ac9be3 100644 --- a/Sources/BuildRequest/RequestBuilds/RUrl.swift +++ b/Sources/BuildRequest/RequestBuilds/RUrl.swift @@ -3,7 +3,7 @@ import Foundation public struct RUrl: RequestProtocol { private let urlString: String - public init(urlString: String) { + public init(_ urlString: String) { self.urlString = urlString } @@ -12,15 +12,22 @@ public struct RUrl: RequestProtocol { } } +extension RUrl { + public init(_ initial: () -> String) { + self.init(initial()) + } +} + extension RUrl { public func withPath(_ path: String?) -> RUrl { + let forwardSlash: Character = "/" if let path = path { - if urlString.last == "/" && path.first == "/" { - return .init(urlString: (urlString + path.dropFirst())) - } else if urlString.last == "/" || path.first == "/" { - return .init(urlString: (urlString + path)) + if urlString.last == forwardSlash && path.first == forwardSlash { + return .init((urlString + path.dropFirst())) + } else if urlString.last == forwardSlash || path.first == forwardSlash { + return .init((urlString + path)) } else { - return .init(urlString: (urlString + "/" + path)) + return .init((urlString + String(forwardSlash) + path)) } } else { return self diff --git a/Sources/BuildRequest/RequestBuilds/Rbody.swift b/Sources/BuildRequest/RequestBuilds/Rbody.swift index 9708a97..951b65b 100644 --- a/Sources/BuildRequest/RequestBuilds/Rbody.swift +++ b/Sources/BuildRequest/RequestBuilds/Rbody.swift @@ -17,6 +17,10 @@ extension Rbody { self.init(string?.toData()) } + public init(_ initial: () -> String?) { + self.init(initial()) + } + public init(_ dictionary: Dictionary) { self.init(dictionary.toData()) } diff --git a/Sources/MRequest/MRequest/MCURLRequest.swift b/Sources/MRequest/MRequest/MCURLRequest.swift index c97dbb9..5bcf1e2 100644 --- a/Sources/MRequest/MRequest/MCURLRequest.swift +++ b/Sources/MRequest/MRequest/MCURLRequest.swift @@ -32,13 +32,13 @@ public struct MCURLRequest { public var toMRequest: MRequest { MRequest { if let urlString = cURLData.url { - RUrl(urlString: urlString) + RUrl(urlString) } if let httpMethod = cURLData.httpMethod { RMethod(HTTPMethod(rawValue: httpMethod)) } if let headers = cURLData.headers { - RHeaders(headers: HTTPHeaders(headers)) + RHeaders(HTTPHeaders(headers)) } if let body = cURLData.postData { Rbody(body.data(using: .utf8)) diff --git a/Sources/MRequest/MRequest/MRequest.swift b/Sources/MRequest/MRequest/MRequest.swift index b42e264..d5d66aa 100644 --- a/Sources/MRequest/MRequest/MRequest.swift +++ b/Sources/MRequest/MRequest/MRequest.swift @@ -1,7 +1,7 @@ import Foundation // MARK: - MRequest -final public class MRequest { +open class MRequest { public var configuration: URLSessionConfiguration? public var urlRequest: URLRequest public var parameter: RequestProtocol @@ -22,8 +22,8 @@ final public class MRequest { } // MARK: Data Request -public extension MRequest { - var dataRequest: DataRequest { +extension MRequest { + public var dataRequest: DataRequest { if storeDataRequest == nil { if let configuration { let session = Session(configuration: configuration) @@ -37,8 +37,8 @@ public extension MRequest { } // MARK: CURL Description -public extension MRequest { - func printCURLRequest( +extension MRequest { + public func printCURLRequest( filename: String = #file, line: Int = #line, funcName: String = #function @@ -60,7 +60,7 @@ public extension MRequest { return self } - func cURLDescription(_ cURL: @escaping(String) -> Void) -> Self { + public func cURLDescription(_ cURL: @escaping(String) -> Void) -> Self { dataRequest .cURLDescription(calling: cURL) return self @@ -77,9 +77,9 @@ public extension MRequest { /// Value used to `await` a `DataResponse` and associated values. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public extension MRequest { +extension MRequest { // MARK: - serializingResponse - func serializingResponse( + public func serializingResponse( using serializer: Serializer, automaticallyCancelling shouldAutomaticallyCancel: Bool = false ) -> DataTask { @@ -90,7 +90,7 @@ public extension MRequest { ) } - func serializingResponse( + public func serializingResponse( using serializer: Serializer, automaticallyCancelling shouldAutomaticallyCancel: Bool = false ) -> DataTask { @@ -102,7 +102,7 @@ public extension MRequest { } // MARK: - Response - func response( + public func response( using serializer: Serializer, automaticallyCancelling shouldAutomaticallyCancel: Bool = false ) async -> DataResponse { @@ -113,7 +113,7 @@ public extension MRequest { .response } - func response( + public func response( using serializer: Serializer, automaticallyCancelling shouldAutomaticallyCancel: Bool = false ) async -> DataResponse { @@ -125,7 +125,7 @@ public extension MRequest { } // MARK: - Result - func result( + public func result( using serializer: Serializer, automaticallyCancelling shouldAutomaticallyCancel: Bool = false ) async -> Result { @@ -136,7 +136,7 @@ public extension MRequest { .result } - func result( + public func result( using serializer: Serializer, automaticallyCancelling shouldAutomaticallyCancel: Bool = false ) async -> Result { @@ -148,53 +148,57 @@ public extension MRequest { } // MARK: - Decodeabe - func serializingDecodeable( + public func serializingDecodeable( _ type: Value.Type = Value.self ) async -> DataTask { dataRequest.serializingDecodable(Value.self) } - func resultDecodeable( + public func resultDecodeable( _ type: Value.Type = Value.self ) async -> Result { await serializingDecodeable(Value.self).result } - func decodeable( + public func decodeable( _ type: Value.Type = Value.self ) async throws -> Value { try await serializingDecodeable(Value.self).value } // MARK: - Data - var serializingData: DataTask { + public var serializingData: DataTask { get async { dataRequest.serializingData() } } - func resultData() async -> Result { - await serializingData.result + public var resultData: Result { + get async { + await serializingData.result + } } - var data: Data { + public var data: Data { get async throws { return try await serializingData.value } } // MARK: - String - var serializingString: DataTask { + public var serializingString: DataTask { get async { dataRequest.serializingString() } } - func resultString() async -> Result { - await serializingString.result + public var resultString: Result { + get async { + await serializingString.result + } } - var string: String { + public var string: String { get async throws { return try await serializingString.value } diff --git a/Tests/BuildRequestTests/BuildRequestTest.swift b/Tests/BuildRequestTests/BuildRequestTest.swift index 098158a..1b3cf70 100644 --- a/Tests/BuildRequestTests/BuildRequestTest.swift +++ b/Tests/BuildRequestTests/BuildRequestTest.swift @@ -2,7 +2,6 @@ import XCTest import BuildRequest /* - RBaseUrl RUrl RPath @@ -18,15 +17,14 @@ import BuildRequest final class BuildRequestTest: XCTestCase { let requests: [RequestProtocol] = [ - RBaseUrl(urlString: "https://test.api.com.rbaseurl"), - RUrl(urlString: "https://test.api.com.rurl"), - RPath(path: "json/rpath"), + RUrl("https://test.api.com.rurl"), + RPath("json/rpath"), Rbody(["username": "yourname", "password": "yourpassword"]), REncoding(JSONEncoding.default), RMethod(.post), - RHeaders(headers: .init(["R1": "RHeaders1", "R2": "RHeaders2", "R3": "RHeaders3"])), + RHeaders(.init(["R1": "RHeaders1", "R2": "RHeaders2", "R3": "RHeaders3"])), RQueryItem("key_RQueryItem", value: "value_RQueryItem"), RQueryItems(["key_RQueryItems": "value_RQueryItems"]), ] @@ -35,7 +33,7 @@ final class BuildRequestTest: XCTestCase { // Given let sequence = _SequenceMany(requests: requests) // When - let rBaseUrl = sequence.getRequest(RBaseUrl.self) + let rBaseUrl = sequence.getRequest(RUrl.self) let rUrl = sequence.getRequest(RUrl.self) let rPath = sequence.getRequest(RPath.self) @@ -64,7 +62,6 @@ final class BuildRequestTest: XCTestCase { // Given let sequence = _SequenceMany(requests: requests) // When - let rBaseUrl = sequence.rBaseUrl let rUrl = sequence.rUrl let rPath = sequence.rPath @@ -76,7 +73,6 @@ final class BuildRequestTest: XCTestCase { let rQueryItem = sequence.rQueryItem let rQueryItems = sequence.rQueryItems // Then - XCTAssertNotNil(rBaseUrl) XCTAssertNotNil(rBody) XCTAssertNotNil(rMethod) @@ -92,14 +88,6 @@ final class BuildRequestTest: XCTestCase { func test_SequenceMany_removeRequestWithType() { // Given var sequence = _SequenceMany(requests: requests) - - // RBaseUrl - XCTAssertNotNil(sequence.getRequest(RBaseUrl.self)) - XCTAssertNotNil(sequence.rBaseUrl) - sequence.remove(RBaseUrl.self) - XCTAssertNil(sequence.getRequest(RBaseUrl.self)) - XCTAssertNil(sequence.rBaseUrl) - // RUrl XCTAssertNotNil(sequence.getRequest(RUrl.self)) XCTAssertNotNil(sequence.rUrl) @@ -161,13 +149,6 @@ final class BuildRequestTest: XCTestCase { // Given var sequence = _SequenceMany(requests: requests) - // RBaseUrl - XCTAssertNotNil(sequence.getRequest(RBaseUrl.self)) - XCTAssertNotNil(sequence.rBaseUrl) - sequence.removeRBaseUrl() - XCTAssertNil(sequence.getRequest(RBaseUrl.self)) - XCTAssertNil(sequence.rBaseUrl) - // RUrl XCTAssertNotNil(sequence.getRequest(RUrl.self)) XCTAssertNotNil(sequence.rUrl) diff --git a/docs/CustomRequestBuilder.md b/docs/CustomRequestBuilder.md new file mode 100644 index 0000000..e5f34b2 --- /dev/null +++ b/docs/CustomRequestBuilder.md @@ -0,0 +1,20 @@ +# Custom Request Builder + +```swift +public struct CustomRequest: RequestProtocol { + /// Initializes a request that does nothing. + @inlinable + public init() { + self.init(internal: ()) + } + + @usableFromInline + init(internal: Void) {} + + @inlinable + public func build(request: inout URLRequest) { + /// nothing todo + } +} + +``` diff --git a/docs/Service.md b/docs/Service.md index f6015ce..b97d5ce 100644 --- a/docs/Service.md +++ b/docs/Service.md @@ -14,10 +14,10 @@ open class BaseAPIService { final public class AuthService: BaseAPIService { - func login(email: String,password: String) -> MRequest { + func login(email: String, password: String) -> MRequest { MRequest { RMethod(.post) - RUrl(urlString: urlString) + RUrl(urlString) //... } } @@ -25,7 +25,7 @@ final public class AuthService: BaseAPIService { func login(email: password) -> MRequest { MRequest { RMethod(.post) - RUrl(urlString: urlString) + RUrl(urlString) //... } }