Comments (5)
nserror-domain | Request explicitly cancelled.
from alamofire.
Without any of your code I can't be sure, but most likely you're not properly retaining the cancellation token from your Combine stream, and it's being deinited, leading to the cancellation. In fact, some number of cancellations are expected when you scope requests to the lifetimes of things like view controllers or SwiftUI views.
Feel free to investigate further and respond with additional details if you find this cancellation is happening without the stream being cancelled or another cancel()
call somewhere.
from alamofire.
Also, I got Domain: URL is not valid error
although the domain was valid.
from alamofire.
In that case you likely need to properly escape your URL
, or use URLComponents
to build it and have the escaping and validation done for you.
from alamofire.
I believe the issue is that the request was not explicitly cancelled it something else.
What did you do?
class NetworkManager {
static let shared = NetworkManager()
private let session = Alamofire.Session(interceptor: interceptor)
private static let credential = OAuthCredential()
// Create the interceptor
private static let authenticator = OAuthAuthenticator(endpoint: RefreshTokenEndpoint.refreshToken)
private static let interceptor = AuthenticationInterceptor(authenticator: authenticator,
credential: credential)
private init() {}
func request<T: Decodable>(_ endpoint: Endpoint) -> AnyPublisher<Result<T, NetworkError>, Never> {
let requestModifier: Session.RequestModifier = { request in
if let dicToStream = endpoint.bodyToStream {
let jsonData = try? JSONSerialization.data(withJSONObject: dicToStream, options: [])
if let jsonData = jsonData {
let inputStream = InputStream(data: jsonData)
request.httpBodyStream = inputStream
}
}
}
NetworkManager.authenticator.endPoint = endpoint
return session.request(endpoint.url,
method: endpoint.httpMethod,
parameters: endpoint.parameters,
encoding: endpoint.httpMethod == .get ? URLEncoding.default : JSONEncoding.default,
headers: HTTPHeaders(endpoint.headers ?? [:]),
requestModifier: requestModifier)
.customValidate(url: endpoint.url)
.cURLDescription { description in
self.logRequest(endpoint, description)
}
.publishResponse(using: CustomResponseSerializable<T>(endpoint: endpoint))
.map { result in
result.value!
}
.eraseToAnyPublisher()
}
}
struct OAuthCredential: AuthenticationCredential {
var accessToken: Token? {
SessionManager.shared.getCurrentUser()?.accessToken
}
var refreshToken: Token? {
SessionManager.shared.getCurrentUser()?.refreshToken
}
// Require refresh if within 5 minutes of expiration
var requiresRefresh: Bool {
guard let refreshToken else { return false }
if let accessToken {
let expiryDate = Date(timeIntervalSince1970: Double(accessToken.expiry / 1000))
return Date(timeIntervalSinceNow: 60 * 5) > expiryDate
}
return false
}
}
class OAuthAuthenticator: Authenticator {
var endPoint: Endpoint
var subscriptions = Set<AnyCancellable>()
var refreshTokenIfNeededUseCase = RefreshTokenIfNeededUseCase()
init(endpoint: Endpoint) {
self.endPoint = endpoint
}
func apply(_ credential: OAuthCredential, to urlRequest: inout URLRequest) {
guard let refreshTokenEndPoint = (endPoint as? RefreshTokenProtocol)?.refreshTokenEndPoint
else {
/// If the request does not require authentication, we can directly return it as unmodified.
return
}
urlRequest.setValue("" + (credential.accessToken?.value ?? ""), forHTTPHeaderField: "interceptor-token")
}
func refresh(_ credential: OAuthCredential, for session: Session, completion: @escaping (Result<OAuthCredential, Error>) -> Void) {
guard let refreshTokenEndPoint = ((endPoint as? RefreshTokenProtocol)?.refreshTokenEndPoint as? RefreshTokenEndpoint)
else {
/// If the request does not require authentication, we can directly return it as unmodified.
return
}
refreshTokenIfNeededUseCase.execute(value: .init(forceRefresh: true)).sink { result in
switch result {
case .success:
completion(.success(OAuthCredential()))
case .failure(let error):
completion(.failure(error))
}
}.store(in: &subscriptions)
}
func didRequest(_ urlRequest: URLRequest, with response: HTTPURLResponse, failDueToAuthenticationError error: Error) -> Bool {
return response.statusCode == 401
}
func isRequest(_ urlRequest: URLRequest, authenticatedWith credential: OAuthCredential) -> Bool {
let token = credential.accessToken?.value ?? ""
return urlRequest.headers["interceptor-token"] == token
}
}
What did you expect to happen?
All the request should be sent successfully
And if it needs to refresh the token and add the authorization token, it should be added. if not, it should not be there
What happened instead?
All the expected work is fine but we have five users with the below issue
The users stuck on api call that was a get request that didn't need to add tokens using the interceptor. "It returned from the apply
method without changing the request."
We sent that request to alamofire using the request
method in our NetworkManager
and it has not returned to success or failure block
But when we removed the authentication interceptor from the session
property for this get request for those users, it worked, and when we put it back, it happened again.
So the problem happend if I use the interceptor in session proberty
private let session = Alamofire.Session(interceptor: interceptor)
But if I removed the interceptor as below it worked
static var session : Session = {
let configuration = URLSessionConfiguration.default
configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
configuration.urlCache = nil // Disable URLCache
return Alamofire.Session(configuration: configuration)
}()
Users devices
Model: iPad 7th Generation (Cellular)
iOS Version: 17.1.1
Model: iPad 9th generation (Cellular)
iOS Version: 17.1.1
Model: iPad 9th generation (Cellular)
iOS Version: 17.1.1
iPad 9th generation (Cellular)
iPad12,2
iOS Version: 17.0.3
Alamofire Environment
**Alamofire Version:5.8.0
Dependency Manager:
**Xcode Version:**15.0.1 (15A507)
Swift Version:
Platform(s) Running Alamofire:
macOS Version Running Xcode:
Demo Project
ℹ Please link to or upload a project we can download that reproduces the issue.
from alamofire.
Related Issues (20)
- Dr
- Add Conformance To ClientTransport From swift-openapi-generator HOT 1
- Timeout responseCode is nil HOT 2
- Add support for visionOS HOT 1
- New version with privacy manifest is not available HOT 3
- Crash - CompositeEventMonitor.request<A>(_:didParseResponse:) HOT 1
- The macOS deployment target 'MACOSX_DEPLOYMENT_TARGET' is set to 10.10, but the range of supported deployment target versions is 10.13 to 14.2.99. (in target 'Alamofire macOS' from project 'Alamofire') HOT 1
- In Xcode's InspectorView, Signature's Kind is Unsigned HOT 1
- Crash on startup with Alamofire 4.9.1 HOT 1
- Cocoapods support for visionOS HOT 4
- Authenticator with Swift Concurrency HOT 3
- Almofire SDK privacy details not reflecting in my project HOT 20
- Not possible to `validate` `WebSocketRequest`? HOT 2
- WebSocketRequest Should Support Validation
- Request for Alamofire Dependency Update to Support Privacy Manifest in AlamofireObjectMapper SDK HOT 1
- Build test target failed with release 5.9
- Significant delay before uploading large files with multipart HOT 3
- Validation()'s variants don't exist for WebSocketRequest
- Privacy manifest for iOS HOT 2
- Privacy Concerns calling systemUptime API HOT 17
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from alamofire.