2 // OAuthWebViewController.swift
5 // Created by Dongri Jin on 2/11/15.
6 // Copyright (c) 2015 Dongri Jin. All rights reserved.
11 #if os(iOS) || os(tvOS)
13 public typealias OAuthViewController = UIViewController
16 public typealias OAuthViewController = WKInterfaceController
19 public typealias OAuthViewController = NSViewController
22 /// Delegate for OAuthWebViewController
23 public protocol OAuthWebViewControllerDelegate: class {
25 #if os(iOS) || os(tvOS)
26 /// Did web view presented (work only without navigation controller)
27 func oauthWebViewControllerDidPresent()
28 /// Did web view dismiss (work only without navigation controller)
29 func oauthWebViewControllerDidDismiss()
32 func oauthWebViewControllerWillAppear()
33 func oauthWebViewControllerDidAppear()
34 func oauthWebViewControllerWillDisappear()
35 func oauthWebViewControllerDidDisappear()
38 /// A web view controller, which handler OAuthSwift authentification.
39 open class OAuthWebViewController: OAuthViewController, OAuthSwiftURLHandlerType {
41 #if os(iOS) || os(tvOS) || os(OSX)
42 /// Delegate for this view
43 public weak var delegate: OAuthWebViewControllerDelegate?
46 #if os(iOS) || os(tvOS)
47 /// If controller have an navigation controller, application top view controller could be used if true
48 public var useTopViewControlerInsteadOfNavigation = false
50 /// Set false to disable present animation.
51 public var presentViewControllerAnimated = true
52 /// Set false to disable dismiss animation.
53 public var dismissViewControllerAnimated = true
55 public var topViewController: UIViewController? {
56 #if !OAUTH_APP_EXTENSIONS
57 return UIApplication.topViewController
63 /// How to present this view controller if parent view controller set
67 case asPopover(relativeToRect: NSRect, ofView : NSView, preferredEdge: NSRectEdge, behavior: NSPopover.Behavior)
68 case transitionFrom(fromViewController: NSViewController, options: NSViewController.TransitionOptions)
69 case animator(animator: NSViewControllerPresentationAnimator)
70 case segue(segueIdentifier: String)
72 public var present: Present = .asModalWindow
75 open func handle(_ url: URL) {
76 // do UI in main thread
77 OAuthSwift.main { [unowned self] in
83 public static var userActivityType: String = "org.github.dongri.oauthswift.connect"
86 open func doHandle(_ url: URL) {
87 #if os(iOS) || os(tvOS)
88 let completion: () -> Void = { [unowned self] in
89 self.delegate?.oauthWebViewControllerDidPresent()
91 if let navigationController = self.navigationController, (!useTopViewControlerInsteadOfNavigation || self.topViewController == nil) {
92 navigationController.pushViewController(self, animated: presentViewControllerAnimated)
93 } else if let p = self.parent {
94 p.present(self, animated: presentViewControllerAnimated, completion: completion)
95 } else if let topViewController = topViewController {
96 topViewController.present(self, animated: presentViewControllerAnimated, completion: completion)
98 // assert no presentation
99 assertionFailure("Failed to present. Maybe add a parent")
102 if url.scheme == "http" || url.scheme == "https" {
103 self.updateUserActivity(OAuthWebViewController.userActivityType, userInfo: nil, webpageURL: url)
106 if let p = self.parent { // default behaviour if this controller affected as child controller
107 switch self.present {
109 p.presentViewControllerAsSheet(self)
111 p.presentViewControllerAsModalWindow(self)
112 // FIXME: if we present as window, window close must detected and oauthswift.cancel() must be called...
113 case .asPopover(let positioningRect, let positioningView, let preferredEdge, let behavior):
114 p.presentViewController(self, asPopoverRelativeTo: positioningRect, of: positioningView, preferredEdge: preferredEdge, behavior: behavior)
115 case .transitionFrom(let fromViewController, let options):
116 let completion: () -> Void = { /*[unowned self] in*/
117 //self.delegate?.oauthWebViewControllerDidPresent()
119 p.transition(from: fromViewController, to: self, options: options, completionHandler: completion)
120 case .animator(let animator):
121 p.presentViewController(self, animator: animator)
122 case .segue(let segueIdentifier):
123 p.performSegue(withIdentifier: NSStoryboardSegue.Identifier(rawValue: segueIdentifier), sender: self) // The segue must display self.view
125 } else if let window = self.view.window {
126 window.makeKeyAndOrderFront(nil)
128 assertionFailure("Failed to present. Add controller into a window or add a parent")
130 // or create an NSWindow or NSWindowController (/!\ keep a strong reference on it)
134 open func dismissWebViewController() {
135 #if os(iOS) || os(tvOS)
136 let completion: () -> Void = { [unowned self] in
137 self.delegate?.oauthWebViewControllerDidDismiss()
139 if let navigationController = self.navigationController, (!useTopViewControlerInsteadOfNavigation || self.topViewController == nil) {
140 navigationController.popViewController(animated: dismissViewControllerAnimated)
141 } else if let parentViewController = self.parent {
142 // The presenting view controller is responsible for dismissing the view controller it presented
143 parentViewController.dismiss(animated: dismissViewControllerAnimated, completion: completion)
144 } else if let topViewController = topViewController {
145 topViewController.dismiss(animated: dismissViewControllerAnimated, completion: completion)
148 self.dismiss(animated: dismissViewControllerAnimated, completion: completion)
153 if self.presenting != nil {
155 if self.parent != nil {
156 self.removeFromParentViewController()
158 } else if let window = self.view.window {
159 window.performClose(nil)
165 #if os(iOS) || os(tvOS)
166 open override func viewWillAppear(_ animated: Bool) {
167 self.delegate?.oauthWebViewControllerWillAppear()
169 open override func viewDidAppear(_ animated: Bool) {
170 self.delegate?.oauthWebViewControllerDidAppear()
172 open override func viewWillDisappear(_ animated: Bool) {
173 self.delegate?.oauthWebViewControllerWillDisappear()
175 open override func viewDidDisappear(_ animated: Bool) {
176 self.delegate?.oauthWebViewControllerDidDisappear()
179 open override func viewWillAppear() {
180 self.delegate?.oauthWebViewControllerWillAppear()
182 open override func viewDidAppear() {
183 self.delegate?.oauthWebViewControllerDidAppear()
185 open override func viewWillDisappear() {
186 self.delegate?.oauthWebViewControllerWillDisappear()
188 open override func viewDidDisappear() {
189 self.delegate?.oauthWebViewControllerDidDisappear()