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)
//...
}
}