[GH-ISSUE #307] OAuthSwift returns "The operation couldn’t be completed. (OAuthSwiftError error -10.)". #186

Closed
opened 2026-03-03 16:46:28 +03:00 by kerem · 9 comments
Owner

Originally created by @the-freshlord on GitHub (Nov 7, 2016).
Original GitHub issue: https://github.com/OAuthSwift/OAuthSwift/issues/307

Description:

When logging in with Facebook, I am able to get the redirect url with the oauthtoken. I have a custom view controller that I set to my instance of OAuthSwift as the authorizeURLHandler. In the custom view controller, I implemented the UIWebViewDelegate method for shouldStartLoadWith where I check for the redirect URL. I then pass the URL into OAuthSwift.handle(). After doing this, I get this error message from OAuthSwift: "The operation couldn’t be completed. (OAuthSwiftError error -10.)". What does this mean and what am I'm doing wrong to get this error?

OAuth Provider (Twitter, Github, ..):

Facebook

OAuth Version:

  • Version 1
  • Version 2

OS (Please fill the version) :

  • iOS :
  • OSX :
  • TVOS :
  • WatchOS :

Installation method:

  • Carthage
  • CocoaPods
  • Manually

Library version:

  • head
  • v1.0.0
  • v0.6
  • other: (Please fill in the version you are using.)

Xcode version:

  • 8.0 (Swift 3.0)

  • 8.0 (Swift 2.3)

  • 7.3.1

  • other: (Please fill in the version you are using.)

  • objective c

Code Sample

let oauthSwift = OAuth2Swift(consumerKey: ConfigManager.shared().facebookAppId, consumerSecret: ConfigManager.shared().facebookSecret, authorizeUrl: _facebookAuthorizationUrlString, accessTokenUrl: _facebookAccessTokenUrlString, responseType: _facebookResponseType)
        let facebookSocialAuthViewController = _internalFacebookSocialAuthWebViewController
        facebookSocialAuthViewController.userCanceledOAuthFlowClosure = {
            failure(nil, true, nil, nil)
        }
        parentController.navigationController?.pushViewController(facebookSocialAuthViewController, animated: true)
        oauthSwift.authorizeURLHandler = facebookSocialAuthViewController
        oauthSwift.authorize(withCallbackURL: _socialRedirectUrl, scope: _facebookScopeParameters, state: generateState(withLength: 20) as String, success: { (credential, response, parameters) in
            let oauthObject = OAuthObject(oAuthTwoWithProviderName: SocialAuthProviderNames.facebook, andOAuthTwoAuthorizationCode: credential.oauthToken, andOAuthTwoRedirectUrlForProvider: self._socialRedirectUrl.absoluteString)!
            self.postSocialAuth(oauthObject, success: { (user: User) in
                success(user)
            }, failure: { (error: Error, response: HTTPURLResponse) in
                if error.localizedDescription == SocialAuthErrors.noEmailProvided {
                    failure(oauthObject, false, error, response)
                    return
                }
                failure(nil, false, error, response)
            })
        }, failure: { (error) in
            failure(nil, false, error, nil)
        })

Here is my custom web vie controller for handling the login.

import UIKit
import OAuthSwift

final class LTFSocialAuthWebViewController: LTFAuthViewController {
    
    // MARK: - Attributes
    fileprivate let _previousCookieAcceptPolicy = HTTPCookieStorage.shared.cookieAcceptPolicy
    fileprivate var _webView = UIWebView()
    fileprivate var _authorizeWithCallBackUrl: URL!
    fileprivate var _targetUrl: URL!
    fileprivate var _socialAuthName: String!
    var userCanceledOAuthFlowClosure: (() -> Void)?
    
    
    // MARK: - Initializers
    init(_ authorizeWithCallBackUrl: URL, socialAuthName: String) {
        super.init(nibName: nil, bundle: nil)
        _authorizeWithCallBackUrl = authorizeWithCallBackUrl
        _socialAuthName = socialAuthName
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}


// MARK: - Lifecycle
extension LTFSocialAuthWebViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        initializeView()
    }
}


// MARK: - OAuthSwiftURLHandlerType
extension LTFSocialAuthWebViewController: OAuthSwiftURLHandlerType {
    func handle(_ url: URL) {
        _targetUrl = url
        loadAuthorizationUrl()
    }
}


// MARK: - UIWebViewDelegate
extension LTFSocialAuthWebViewController: UIWebViewDelegate {
    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        guard let authorizationUrl = request.url, authorizationUrl.host == _authorizeWithCallBackUrl.host else {
            return true
        }
        OAuthSwift.handle(url: authorizationUrl)
        _ = navigationController?.popViewController(animated: true)
        return false
    }
}


// MARK: - Private Instance Methods
extension LTFSocialAuthWebViewController {
    fileprivate func initializeView() {
        navigationItem.title = _socialAuthName
        navigationItem.backBarButtonItem = UIBarButtonItem(image: UIImage(named: "icon-previous"), style: .plain, target: self, action: #selector(cancelButtonTapped))
        _webView.frame = UIScreen.main.bounds
        _webView.scalesPageToFit = true
        _webView.delegate = self
        view.addSubview(_webView)
    }
    
    fileprivate func loadAuthorizationUrl() {
        HTTPCookieStorage.shared.cookieAcceptPolicy = .always
        let cookies = HTTPCookieStorage.shared.cookies
        HTTPCookieStorage.shared.setCookies(cookies!, for: _targetUrl, mainDocumentURL: _targetUrl)
        _webView.loadRequest(URLRequest(url: _targetUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0))
    }
    
    @objc fileprivate func cancelButtonTapped() {
        HTTPCookieStorage.shared.cookieAcceptPolicy = _previousCookieAcceptPolicy
        _ = navigationController?.popViewController(animated: true)
        guard let closure = userCanceledOAuthFlowClosure else { return }
        closure()
    }
}
Originally created by @the-freshlord on GitHub (Nov 7, 2016). Original GitHub issue: https://github.com/OAuthSwift/OAuthSwift/issues/307 ### Description: When logging in with Facebook, I am able to get the redirect url with the oauthtoken. I have a custom view controller that I set to my instance of OAuthSwift as the authorizeURLHandler. In the custom view controller, I implemented the UIWebViewDelegate method for `shouldStartLoadWith` where I check for the redirect URL. I then pass the URL into `OAuthSwift.handle()`. After doing this, I get this error message from OAuthSwift: "The operation couldn’t be completed. (OAuthSwiftError error -10.)". What does this mean and what am I'm doing wrong to get this error? ### OAuth Provider (Twitter, Github, ..): Facebook ### OAuth Version: - [ ] Version 1 - [x] Version 2 ### OS (Please fill the version) : - [x] iOS : - [ ] OSX : - [ ] TVOS : - [ ] WatchOS : ### Installation method: - [ ] Carthage - [x] CocoaPods - [ ] Manually ### Library version: - [x] head - [ ] v1.0.0 - [ ] v0.6 - [ ] other: (Please fill in the version you are using.) ### Xcode version: - [x] 8.0 (Swift 3.0) - [ ] 8.0 (Swift 2.3) - [ ] 7.3.1 - [ ] other: (Please fill in the version you are using.) - [ ] objective c ### Code Sample ``` let oauthSwift = OAuth2Swift(consumerKey: ConfigManager.shared().facebookAppId, consumerSecret: ConfigManager.shared().facebookSecret, authorizeUrl: _facebookAuthorizationUrlString, accessTokenUrl: _facebookAccessTokenUrlString, responseType: _facebookResponseType) let facebookSocialAuthViewController = _internalFacebookSocialAuthWebViewController facebookSocialAuthViewController.userCanceledOAuthFlowClosure = { failure(nil, true, nil, nil) } parentController.navigationController?.pushViewController(facebookSocialAuthViewController, animated: true) oauthSwift.authorizeURLHandler = facebookSocialAuthViewController oauthSwift.authorize(withCallbackURL: _socialRedirectUrl, scope: _facebookScopeParameters, state: generateState(withLength: 20) as String, success: { (credential, response, parameters) in let oauthObject = OAuthObject(oAuthTwoWithProviderName: SocialAuthProviderNames.facebook, andOAuthTwoAuthorizationCode: credential.oauthToken, andOAuthTwoRedirectUrlForProvider: self._socialRedirectUrl.absoluteString)! self.postSocialAuth(oauthObject, success: { (user: User) in success(user) }, failure: { (error: Error, response: HTTPURLResponse) in if error.localizedDescription == SocialAuthErrors.noEmailProvided { failure(oauthObject, false, error, response) return } failure(nil, false, error, response) }) }, failure: { (error) in failure(nil, false, error, nil) }) ``` Here is my custom web vie controller for handling the login. ``` import UIKit import OAuthSwift final class LTFSocialAuthWebViewController: LTFAuthViewController { // MARK: - Attributes fileprivate let _previousCookieAcceptPolicy = HTTPCookieStorage.shared.cookieAcceptPolicy fileprivate var _webView = UIWebView() fileprivate var _authorizeWithCallBackUrl: URL! fileprivate var _targetUrl: URL! fileprivate var _socialAuthName: String! var userCanceledOAuthFlowClosure: (() -> Void)? // MARK: - Initializers init(_ authorizeWithCallBackUrl: URL, socialAuthName: String) { super.init(nibName: nil, bundle: nil) _authorizeWithCallBackUrl = authorizeWithCallBackUrl _socialAuthName = socialAuthName } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } } // MARK: - Lifecycle extension LTFSocialAuthWebViewController { override func viewDidLoad() { super.viewDidLoad() initializeView() } } // MARK: - OAuthSwiftURLHandlerType extension LTFSocialAuthWebViewController: OAuthSwiftURLHandlerType { func handle(_ url: URL) { _targetUrl = url loadAuthorizationUrl() } } // MARK: - UIWebViewDelegate extension LTFSocialAuthWebViewController: UIWebViewDelegate { func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { guard let authorizationUrl = request.url, authorizationUrl.host == _authorizeWithCallBackUrl.host else { return true } OAuthSwift.handle(url: authorizationUrl) _ = navigationController?.popViewController(animated: true) return false } } // MARK: - Private Instance Methods extension LTFSocialAuthWebViewController { fileprivate func initializeView() { navigationItem.title = _socialAuthName navigationItem.backBarButtonItem = UIBarButtonItem(image: UIImage(named: "icon-previous"), style: .plain, target: self, action: #selector(cancelButtonTapped)) _webView.frame = UIScreen.main.bounds _webView.scalesPageToFit = true _webView.delegate = self view.addSubview(_webView) } fileprivate func loadAuthorizationUrl() { HTTPCookieStorage.shared.cookieAcceptPolicy = .always let cookies = HTTPCookieStorage.shared.cookies HTTPCookieStorage.shared.setCookies(cookies!, for: _targetUrl, mainDocumentURL: _targetUrl) _webView.loadRequest(URLRequest(url: _targetUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)) } @objc fileprivate func cancelButtonTapped() { HTTPCookieStorage.shared.cookieAcceptPolicy = _previousCookieAcceptPolicy _ = navigationController?.popViewController(animated: true) guard let closure = userCanceledOAuthFlowClosure else { return } closure() } } ```
kerem 2026-03-03 16:46:28 +03:00
Author
Owner

@phimage commented on GitHub (Nov 7, 2016):

I don't understand why you can see only error code, I implement CustomStringConvertible (maybe CustomDebugStringConvertiblemust also be implemented)

OAuthSwiftError error -10 -> retain, see https://github.com/OAuthSwift/OAuthSwift/blob/master/Sources/OAuthSwiftError.swift

You must retain your oauthSwift object somewhere, have a head reference on it
let oauthSwift = OAuth2Swift is not good if after you do not store it elsewhere

<!-- gh-comment-id:258769973 --> @phimage commented on GitHub (Nov 7, 2016): I don't understand why you can see only error code, I implement `CustomStringConvertible` (maybe `CustomDebugStringConvertible`must also be implemented) OAuthSwiftError error -10 -> retain, see https://github.com/OAuthSwift/OAuthSwift/blob/master/Sources/OAuthSwiftError.swift You must retain your oauthSwift object somewhere, have a head reference on it `let oauthSwift = OAuth2Swift` is not good if after you do not store it elsewhere
Author
Owner

@the-freshlord commented on GitHub (Nov 7, 2016):

Where would it need to be stored if it is a retain problem. Or should it be a var?

<!-- gh-comment-id:258835676 --> @the-freshlord commented on GitHub (Nov 7, 2016): Where would it need to be stored if it is a retain problem. Or should it be a var?
Author
Owner

@phimage commented on GitHub (Nov 7, 2016):

yes a var into your controller (see demo app for instance)

you authorise only one time authorize(withCallbackURL:
then you can use the object oauthSwift to do some request from any functions of your controller

<!-- gh-comment-id:258838315 --> @phimage commented on GitHub (Nov 7, 2016): yes a `var` into your controller (see demo app for instance) you authorise only one time `authorize(withCallbackURL:` then you can use the object `oauthSwift` to do some request from any functions of your controller
Author
Owner

@the-freshlord commented on GitHub (Nov 7, 2016):

I was able to get it to work. I looked at the demo view controller example and saw you had an instance variable for retaining the oauthswift object. I set it after creating a OAuthSwift object in my class for handling social auth.

<!-- gh-comment-id:258841456 --> @the-freshlord commented on GitHub (Nov 7, 2016): I was able to get it to work. I looked at the demo view controller example and saw you had an instance variable for retaining the oauthswift object. I set it after creating a OAuthSwift object in my class for handling social auth.
Author
Owner

@the-freshlord commented on GitHub (Nov 7, 2016):

Out of curiosity, could it cause a retain cycle?

<!-- gh-comment-id:258853874 --> @the-freshlord commented on GitHub (Nov 7, 2016): Out of curiosity, could it cause a retain cycle?
Author
Owner

@phimage commented on GitHub (Nov 7, 2016):

No. You must retain it because we do the maximum to not retain anything internally (and our retain exception is thrown in that case instead of keeping reference to the objects)

<!-- gh-comment-id:258882741 --> @phimage commented on GitHub (Nov 7, 2016): No. You must retain it because we do the maximum to not retain anything internally (and our `retain` exception is thrown in that case instead of keeping reference to the objects)
Author
Owner

@the-freshlord commented on GitHub (Nov 7, 2016):

Now I am getting a new issue. When getting the oauthcode in the redirect, this is what it looks like: https://app.baseapp.tsl.io/?code=AQBmpqCsISKO-qpynrW1C7syI34HK2qGn0yI4_fmaqNKE_IqEbqxHgwRd9gJ43WT8VBWkTaetp6l61bWp-yhQ45W2v2W217GTTgrRv33yiN5QXJv-Z9ITVBsU8Yjv-0qIavzpVpoou-MHWxkDeNxqBqcMjUjEQjNpOq5KC8aSBYa-fGLNAyglvdX6P78m-7cPafoQGJ_73EJ4yMLKbX23TIt1odtcV9JAG9L8THaDsjCX7Iwb15Ov_eNN1W7PGX9Ecg5GLAlKfJxCtRtZPreMuhSc5ZfNqEsW9XAM6Fs-TH_L3wIzt6ZEkaW_Yol-dRy026rql8rhvGvboTus0DjkH35&state=2iQTuirDDt0783Kipz4V#_=_.
Now when getting this token, it changes to EAAXDphYBK2wBAIQCAeEe8S1OuTTcu8m5jBD8rr2XZBc7eCoMeHyC8q20cWEXo559ByJNSjEYxANZAPZBs8FMHvoscZC3B1Orjes1WtVQORCgmgi09MeQynVt30lH7mWdq2Rlbm1OkiYfvZB5l649sPerBO95Cl24ZD. Why does it change?
When accessing credential.oauthToken, the value should be the one that is in the redirect url.

<!-- gh-comment-id:258998135 --> @the-freshlord commented on GitHub (Nov 7, 2016): Now I am getting a new issue. When getting the oauthcode in the redirect, this is what it looks like: `https://app.baseapp.tsl.io/?code=AQBmpqCsISKO-qpynrW1C7syI34HK2qGn0yI4_fmaqNKE_IqEbqxHgwRd9gJ43WT8VBWkTaetp6l61bWp-yhQ45W2v2W217GTTgrRv33yiN5QXJv-Z9ITVBsU8Yjv-0qIavzpVpoou-MHWxkDeNxqBqcMjUjEQjNpOq5KC8aSBYa-fGLNAyglvdX6P78m-7cPafoQGJ_73EJ4yMLKbX23TIt1odtcV9JAG9L8THaDsjCX7Iwb15Ov_eNN1W7PGX9Ecg5GLAlKfJxCtRtZPreMuhSc5ZfNqEsW9XAM6Fs-TH_L3wIzt6ZEkaW_Yol-dRy026rql8rhvGvboTus0DjkH35&state=2iQTuirDDt0783Kipz4V#_=_`. Now when getting this token, it changes to `EAAXDphYBK2wBAIQCAeEe8S1OuTTcu8m5jBD8rr2XZBc7eCoMeHyC8q20cWEXo559ByJNSjEYxANZAPZBs8FMHvoscZC3B1Orjes1WtVQORCgmgi09MeQynVt30lH7mWdq2Rlbm1OkiYfvZB5l649sPerBO95Cl24ZD`. Why does it change? When accessing `credential.oauthToken`, the value should be the one that is in the redirect url.
Author
Owner

@the-freshlord commented on GitHub (Nov 7, 2016):

Actually figured out its the access token. But is there still a way to get the code thats in the redirect URL?

<!-- gh-comment-id:259003046 --> @the-freshlord commented on GitHub (Nov 7, 2016): Actually figured out its the access token. But is there still a way to get the code thats in the redirect URL?
Author
Owner

@phimage commented on GitHub (Nov 8, 2016):

a new topic, a new issue

code is just a temporary var to request then the oauth token using url accessTokenUrl
I think this code is not stored anywhere and if last request don't provide it you cannot have it in "parameters" (in success callback)

<!-- gh-comment-id:259063692 --> @phimage commented on GitHub (Nov 8, 2016): a new topic, a new issue code is just a temporary var to request then the oauth token using url accessTokenUrl I think this code is not stored anywhere and if last request don't provide it you cannot have it in "parameters" (in success callback)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/OAuthSwift#186
No description provided.