2 // NSError+OAuthSwift.swift
5 // Created by Goessler, Florian on 04/04/16.
6 // Copyright © 2016 Dongri Jin. All rights reserved.
11 public extension NSError {
13 /// Checks the headers contained in the userInfo whether this error was caused by an
14 /// expired/invalid access token.
16 /// Criteria for invalid token error: WWW-Authenticate header contains a field "error" with
17 /// value "invalid_token".
19 /// Also implements a special handling for the Facebook API, which indicates invalid tokens in a
20 /// different manner. See https://developers.facebook.com/docs/graph-api/using-graph-api#errors
21 public var isExpiredToken: Bool {
22 guard self.domain == NSURLErrorDomain else {
26 if let reponseHeaders = self.userInfo["Response-Headers"] as? [String: String],
27 let authenticateHeader = reponseHeaders["WWW-Authenticate"] ?? reponseHeaders["Www-Authenticate"] {
28 let headerDictionary = authenticateHeader.headerDictionary
29 if let error = headerDictionary["error"], error == "invalid_token" || error == "\"invalid_token\"" {
33 if let body = self.userInfo["Response-Body"] as? String,
34 let bodyData = body.data(using: OAuthSwiftDataEncoding),
35 let json = try? JSONSerialization.jsonObject(with: bodyData, options: []),
36 let jsonDic = json as? [String: AnyObject] {
37 if let error = jsonDic["error"] as? String, error == "invalid_token" || error == "\"invalid_token\"" {
40 if let errors = jsonDic["errors"] as? [[String: AnyObject]] {
42 if let errorType = error["errorType"] as? String, errorType == "invalid_token" {
50 // Detect access token expiration errors from facebook
51 // Docu: https://developers.facebook.com/docs/graph-api/using-graph-api#errors
53 if let urlString = self.userInfo[NSURLErrorFailingURLErrorKey] as? String, urlString.contains("graph.facebook.com") {
54 if let body = self.userInfo["Response-Body"] as? String,
55 let bodyData = body.data(using: OAuthSwiftDataEncoding),
56 let json = try? JSONSerialization.jsonObject(with: bodyData, options: []),
57 let jsonDic = json as? [String: AnyObject] {
58 let errorCode = jsonDic["error"]?["code"] as? Int
59 let errorSubCode = jsonDic["error"]?["error_subcode"] as? Int
60 if (errorCode == 102 && errorSubCode == nil) || errorSubCode == 463 || errorSubCode == 467 {