added iOS source code
[wl-app.git] / iOS / Pods / OAuthSwift / Sources / OAuthSwiftURLHandlerType.swift
1 //
2 //  OAuthSwiftURLHandlerType.swift
3 //  OAuthSwift
4 //
5 //  Created by phimage on 11/05/15.
6 //  Copyright (c) 2015 Dongri Jin. All rights reserved.
7 //
8
9 import Foundation
10
11 #if os(iOS) || os(tvOS)
12     import UIKit
13 #elseif os(watchOS)
14     import WatchKit
15 #elseif os(OSX)
16     import AppKit
17 #endif
18
19 @objc public protocol OAuthSwiftURLHandlerType {
20     func handle(_ url: URL)
21 }
22
23 // MARK: Open externally
24 open class OAuthSwiftOpenURLExternally: OAuthSwiftURLHandlerType {
25
26     public static var sharedInstance: OAuthSwiftOpenURLExternally = OAuthSwiftOpenURLExternally()
27
28     @objc open func handle(_ url: URL) {
29         #if os(iOS) || os(tvOS)
30             #if !OAUTH_APP_EXTENSIONS
31                 UIApplication.shared.openURL(url)
32             #endif
33         #elseif os(watchOS)
34         // WATCHOS: not implemented
35         #elseif os(OSX)
36             NSWorkspace.shared.open(url)
37         #endif
38     }
39 }
40
41 // MARK: Open SFSafariViewController
42 #if os(iOS)
43 import SafariServices
44
45     @available(iOS 9.0, *)
46     open class SafariURLHandler: NSObject, OAuthSwiftURLHandlerType, SFSafariViewControllerDelegate {
47
48         public typealias UITransion = (_ controller: SFSafariViewController, _ handler: SafariURLHandler) -> Void
49
50         weak open var oauthSwift: OAuthSwift?
51         open var present: UITransion
52         open var dismiss: UITransion
53         /// retains observers
54         var observers = [String: NSObjectProtocol]()
55
56         open var factory: (_ URL: URL) -> SFSafariViewController = {URL in
57             return SFSafariViewController(url: URL)
58         }
59
60         /// delegates
61         open weak var delegate: SFSafariViewControllerDelegate?
62
63         // configure default presentation and dismissal code
64
65         open var animated: Bool = true
66         open var presentCompletion: (() -> Void)?
67         open var dismissCompletion: (() -> Void)?
68         open var delay: UInt32? = 1
69
70         /// init
71         public init(viewController: UIViewController, oauthSwift: OAuthSwift) {
72             self.oauthSwift = oauthSwift
73             self.present = { [weak viewController] controller, handler in
74                 viewController?.present(controller, animated: handler.animated, completion: handler.presentCompletion)
75             }
76             self.dismiss = { [weak viewController] _, handler in
77                 viewController?.dismiss(animated: handler.animated, completion: handler.dismissCompletion)
78             }
79         }
80
81         public init(present: @escaping UITransion, dismiss: @escaping UITransion, oauthSwift: OAuthSwift) {
82             self.oauthSwift = oauthSwift
83             self.present = present
84             self.dismiss = dismiss
85         }
86
87         @objc open func handle(_ url: URL) {
88             let controller = factory(url)
89             controller.delegate = self
90
91             // present controller in main thread
92             OAuthSwift.main { [weak self] in
93                 guard let this = self else {
94                     return
95                 }
96                 if let delay = this.delay { // sometimes safari show a blank view..
97                     sleep(delay)
98                 }
99                 this.present(controller, this)
100             }
101
102             let key = UUID().uuidString
103
104             observers[key] = OAuthSwift.notificationCenter.addObserver(
105                 forName: NSNotification.Name.OAuthSwiftHandleCallbackURL,
106                 object: nil,
107                 queue: OperationQueue.main,
108                 using: { [weak self] _ in
109                     guard let this = self else {
110                         return
111                     }
112                     if let observer = this.observers[key] {
113                         OAuthSwift.notificationCenter.removeObserver(observer)
114                         this.observers.removeValue(forKey: key)
115                     }
116                     OAuthSwift.main {
117                         this.dismiss(controller, this)
118                     }
119                 }
120             )
121         }
122
123         /// Clear internal observers on authentification flow
124         open func clearObservers() {
125             clearLocalObservers()
126             self.oauthSwift?.removeCallbackNotificationObserver()
127         }
128
129         open func clearLocalObservers() {
130             for (_, observer) in observers {
131                 OAuthSwift.notificationCenter.removeObserver(observer)
132             }
133             observers.removeAll()
134         }
135
136         /// SFSafariViewControllerDelegate
137         public func safariViewController(_ controller: SFSafariViewController, activityItemsFor URL: Foundation.URL, title: String?) -> [UIActivity] {
138             return self.delegate?.safariViewController?(controller, activityItemsFor: URL, title: title) ?? []
139         }
140
141         public func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
142             // "Done" pressed
143             self.clearObservers()
144             self.delegate?.safariViewControllerDidFinish?(controller)
145         }
146
147         public func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
148             self.delegate?.safariViewController?(controller, didCompleteInitialLoad: didLoadSuccessfully)
149         }
150
151     }
152
153 #endif
154
155 // MARK: Open url using NSExtensionContext
156 open class ExtensionContextURLHandler: OAuthSwiftURLHandlerType {
157
158     fileprivate var extensionContext: NSExtensionContext
159
160     public init(extensionContext: NSExtensionContext) {
161         self.extensionContext = extensionContext
162     }
163
164     @objc open func handle(_ url: URL) {
165         extensionContext.open(url, completionHandler: nil)
166     }
167 }