Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add session delegate to initializer #44

Merged
merged 6 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ on:
jobs:
test:
name: Run tests
runs-on: macos-12
runs-on: macos-15
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Change Xcode
run: sudo xcode-select -s /Applications/Xcode_13.4.1.app
run: sudo xcode-select -s /Applications/Xcode_15.0.1.app
- name: Build and test
run: swift test --enable-code-coverage --disable-automatic-resolution
run: swift test --enable-code-coverage --disable-automatic-resolution
14 changes: 7 additions & 7 deletions Apexy.podspec
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
Pod::Spec.new do |s|
s.name = "Apexy"
s.version = "1.7.3"
s.version = "1.7.4"
s.summary = "HTTP transport library"
s.homepage = "https://github.com/RedMadRobot/apexy-ios"
s.license = { :type => "MIT"}
s.author = { "Alexander Ignatiev" => "[email protected]" }
s.source = { :git => "https://github.com/RedMadRobot/apexy-ios.git", :tag => "#{s.version}" }

s.ios.deployment_target = "11.0"
s.tvos.deployment_target = "11.0"
s.osx.deployment_target = "10.13"
s.watchos.deployment_target = "4.0"
s.ios.deployment_target = "13.0"
s.tvos.deployment_target = "13.0"
s.osx.deployment_target = "10.15"
s.watchos.deployment_target = "6.0"

s.swift_version = "5.3"

s.subspec 'Core' do |sp|
sp.source_files = "Sources/Apexy/*.swift"
sp.source_files = "Sources/Apexy/**/*.swift"
end

s.subspec 'Alamofire' do |sp|
sp.source_files = "Sources/ApexyAlamofire/*.swift"
sp.dependency "Apexy/Core"
sp.dependency "Alamofire", '~>5.0'
sp.dependency "Alamofire", '~>5.6'
end

s.subspec 'URLSession' do |sp|
Expand Down
6 changes: 3 additions & 3 deletions Example/Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -791,7 +791,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 42LRQS6X44;
INFOPLIST_FILE = "Example/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -812,7 +812,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 42LRQS6X44;
INFOPLIST_FILE = "Example/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
15 changes: 2 additions & 13 deletions Example/Example/Sources/Business Logic/Service/BookService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,18 @@ import ExampleAPI
typealias Book = ExampleAPI.Book

protocol BookService {

@discardableResult
func fetchBooks(completion: @escaping (Result<[Book], Error>) -> Void) -> Progress

@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
func fetchBooks() async throws -> [Book]
}


final class BookServiceImpl: BookService {

let apiClient: Client
let apiClient: ConcurrencyClient

init(apiClient: Client) {
init(apiClient: ConcurrencyClient) {
self.apiClient = apiClient
}

func fetchBooks(completion: @escaping (Result<[Book], Error>) -> Void) -> Progress {
let endpoint = BookListEndpoint()
return apiClient.request(endpoint, completionHandler: completion)
}

@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
func fetchBooks() async throws -> [Book] {
let endpoint = BookListEndpoint()
return try await apiClient.request(endpoint)
Expand Down
28 changes: 3 additions & 25 deletions Example/Example/Sources/Business Logic/Service/FileService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,24 @@ import Apexy
import ExampleAPI

protocol FileService {

@discardableResult
func upload(file: URL, completion: @escaping (Result<Void, Error>) -> Void) -> Progress

@discardableResult
func upload(stream: InputStream, size: Int, completion: @escaping (Result<Void, Error>) -> Void) -> Progress

@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
func upload(file: URL) async throws

@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
func upload(stream: InputStream, size: Int) async throws
}


final class FileServiceImpl: FileService {

let apiClient: Client
let apiClient: ConcurrencyClient

init(apiClient: Client) {
init(apiClient: ConcurrencyClient) {
self.apiClient = apiClient
}

func upload(file: URL, completion: @escaping (Result<Void, Error>) -> Void) -> Progress {
let endpoint = FileUploadEndpoint(fileURL: file)
return apiClient.upload(endpoint, completionHandler: completion)
}

func upload(stream: InputStream, size: Int, completion: @escaping (Result<Void, Error>) -> Void) -> Progress {
let endpoint = StreamUploadEndpoint(stream: stream, size: size)
return apiClient.upload(endpoint, completionHandler: completion)
}

@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)

func upload(file: URL) async throws {
let endpoint = FileUploadEndpoint(fileURL: file)
return try await apiClient.upload(endpoint)
}

@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
func upload(stream: InputStream, size: Int) async throws {
let endpoint = StreamUploadEndpoint(stream: stream, size: size)
return try await apiClient.upload(endpoint)
Expand Down
14 changes: 6 additions & 8 deletions Example/Example/Sources/Business Logic/ServiceLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ final class ServiceLayer {

static let shared = ServiceLayer()

private(set) lazy var apiClient: Client = {
return AlamofireClient(
baseURL: URL(string: "https://library.mock-object.redmadserver.com/api/v1/")!,
configuration: .ephemeral,
responseObserver: { [weak self] request, response, data, error in
self?.validateSession(responseError: error)
})
}()
private(set) lazy var apiClient: ConcurrencyClient = AlamofireClient(
baseURL: URL(string: "https://library.mock-object.redmadserver.com/api/v1/")!,
configuration: .ephemeral,
responseObserver: { [weak self] request, response, data, error in
self?.validateSession(responseError: error)
})

private(set) lazy var bookService: BookService = BookServiceImpl(apiClient: apiClient)

Expand Down
59 changes: 1 addition & 58 deletions Example/Example/Sources/Presentation/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ class ViewController: UIViewController {
@IBAction private func performRequest() {
activityView.isHidden = false

guard #available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) else { performLegacyRequest(); return }

task = Task {
do {
let books = try await bookService.fetchBooks()
Expand All @@ -43,25 +41,9 @@ class ViewController: UIViewController {
}
}

private func performLegacyRequest() {
progress = bookService.fetchBooks() { [weak self] result in
guard let self = self else { return }
self.activityView.isHidden = true
switch result {
case .success(let books):
self.show(books: books)
case .failure(let error):
self.show(error: error)
}
}
}


@IBAction private func upload() {
guard let file = Bundle.main.url(forResource: "Info", withExtension: "plist") else { return }
activityView.isHidden = false

guard #available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) else { legacyUpload(with: file); return }

task = Task {
do {
Expand All @@ -73,27 +55,12 @@ class ViewController: UIViewController {
activityView.isHidden = true
}
}

private func legacyUpload(with file: URL) {
progress = fileService.upload(file: file) { [weak self] result in
guard let self = self else { return }
self.activityView.isHidden = true
switch result {
case .success:
self.showOKUpload()
case .failure(let error):
self.show(error: error)
}
}
}


@IBAction private func uploadStream() {
let streamer = Streamer()
self.streamer = streamer
activityView.isHidden = false

guard #available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) else { legacyUploadStream(with: streamer); return }

streamer.run()

task = Task {
Expand All @@ -106,30 +73,6 @@ class ViewController: UIViewController {
}
}

private func legacyUploadStream(with streamer: Streamer) {
progress = fileService.upload(
stream: streamer.boundStreams.input,
size: streamer.totalDataSize) { [weak self] result in
guard let self = self else { return }
self.activityView.isHidden = true
switch result {
case .success:
self.showOKUpload()
case .failure(let error):
self.show(error: error)
self.streamer = nil
}
}
streamer.run()

observation = progress?.observe(\.fractionCompleted, options: [.new]) { [weak self] (progress, value) in
DispatchQueue.main.async {
let percent = (value.newValue ?? 0) * 100
self?.resultLabel.text = "Progress: \(String(format: "%.0f", percent))%"
}
}
}

@IBAction private func cancel() {
if #available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) {
(task as? Task<Void, Never>)?.cancel()
Expand Down
16 changes: 8 additions & 8 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
PODS:
- Alamofire (5.4.1)
- Apexy (1.7.2):
- Apexy/Alamofire (= 1.7.2)
- Apexy/Alamofire (1.7.2):
- Alamofire (~> 5.0)
- Alamofire (5.8.1)
- Apexy (1.7.4):
- Apexy/Alamofire (= 1.7.4)
- Apexy/Alamofire (1.7.4):
- Alamofire (~> 5.6)
- Apexy/Core
- Apexy/Core (1.7.2)
- Apexy/Core (1.7.4)

DEPENDENCIES:
- Apexy (from `../`)
Expand All @@ -19,8 +19,8 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
Alamofire: 2291f7d21ca607c491dd17642e5d40fdcda0e65c
Apexy: 984a2c615adf4b5af3432859d768a7a3dec51907
Alamofire: 3ca42e259043ee0dc5c0cdd76c4bc568b8e42af7
Apexy: a3218097135e746fd7c9215da167521f9275df23

PODFILE CHECKSUM: f86a90e7590ccb3aa7caeceaf315abe256650c66

Expand Down
8 changes: 4 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import PackageDescription
let package = Package(
name: "Apexy",
platforms: [
.macOS(.v10_13),
.iOS(.v11),
.tvOS(.v11),
.watchOS(.v4)
.macOS(.v10_15),
.iOS(.v13),
.tvOS(.v13),
.watchOS(.v6)
],
products: [
.library(name: "Apexy", targets: ["ApexyURLSession"]),
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ Split the network layer into folders:

## Requirements

- iOS 11.0+ / macOS 10.13+ / tvOS 11.0+ / watchOS 4.0+
- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+
- Xcode 12+
- Swift 5.3+

Expand Down
2 changes: 1 addition & 1 deletion README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public struct FileUploadEndpoint: UploadEndpoint {

## Требования

- iOS 11.0+ / macOS 10.13+ / tvOS 11.0+ / watchOS 4.0+
- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+
- Xcode 12+
- Swift 5.3+

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension URLSession {
/// - delegate: Delegate to get events about request (NOT WORKING💀)
/// - Returns: Tuple with Data and URLResponse
public func data(
for request: URLRequest,
forRequest request: URLRequest,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change in the public API, so I think you should update the major version in the podspec file. Or at least a minor version 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need this extension at all now. it was implemented at time when URLSession had their async/await methods ready for use only since iOS 15. so to make URLSessionClient implementataion for iOS 13 and easy to read i have made this extension with async/await methods.

now this methods are in URLSession available since iOS 13 so you can just delete this file and it will work justs fine

Copy link
Contributor

@laqiguy laqiguy Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and also now you can get rid of AsyncAwaitHelper file too
#42 will be fixed also

delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse) {
return try await AsyncAwaitHelper.adaptToAsync(dataTaskClosure: { continuation in
let task = dataTask(with: request) { data, response, error in
Expand Down
7 changes: 6 additions & 1 deletion Sources/ApexyURLSession/URLSessionClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@ open class URLSessionClient: Client, CombineClient {
/// - Parameters:
/// - baseURL: Base `URL`.
/// - configuration: The configuration used to construct the managed session.
/// - delegate: The delegate of URLSession.
/// - completionQueue: The serial operation queue used to dispatch all completion handlers. `.main` by default.
/// - responseObserver: The closure to be called after each response.
public convenience init(
baseURL: URL,
configuration: URLSessionConfiguration = .default,
delegate: URLSessionDelegate? = nil,
completionQueue: DispatchQueue = .main,
responseObserver: ResponseObserver? = nil) {

self.init(
requestAdapter: BaseRequestAdapter(baseURL: baseURL),
configuration: configuration,
delegate: delegate,
completionQueue: completionQueue,
responseObserver: responseObserver)
}
Expand All @@ -38,16 +41,18 @@ open class URLSessionClient: Client, CombineClient {
/// - Parameters:
/// - requestAdapter: RequestAdapter used to adapt a `URLRequest`.
/// - configuration: The configuration used to construct the managed session.
/// - delegate: The delegate of URLSession.
/// - completionQueue: The serial operation queue used to dispatch all completion handlers. `.main` by default.
/// - responseObserver: The closure to be called after each response.
public init(
requestAdapter: RequestAdapter,
configuration: URLSessionConfiguration = .default,
delegate: URLSessionDelegate? = nil,
completionQueue: DispatchQueue = .main,
responseObserver: ResponseObserver? = nil) {

self.requestAdapter = requestAdapter
self.session = URLSession(configuration: configuration)
self.session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
self.completionQueue = completionQueue
self.responseObserver = responseObserver
}
Expand Down
Loading