Skip to content

Commit

Permalink
Merge pull request #2 from codefirst/twitter-auth
Browse files Browse the repository at this point in the history
Twitter auth
  • Loading branch information
banjun committed Mar 15, 2015
2 parents 8f60629 + bc8b060 commit edb140d
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 10 deletions.
6 changes: 4 additions & 2 deletions AsakusaSatellite.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ Pod::Spec.new do |s|
s.license = "MIT"
s.author = { "banjun" => "[email protected]" }
s.ios.deployment_target = "8.0"
# s.osx.deployment_target = "10.10"
s.osx.deployment_target = "10.10"
s.source = { :git => "https://github.com/codefirst/AsakusaSatelliteSwiftClient.git", :tag => "0.0.1" }
s.source_files = "Classes", "Classes/**/*.{h,m,swift}"
s.source_files = 'Classes/*.swift'
s.ios.source_files = 'Classes/ios/*.swift'
s.osx.source_files = ''
s.requires_arc = true
s.dependency "Alamofire", "~> 1.1"
s.dependency "SwiftyJSON", "~> 2.1"
Expand Down
13 changes: 7 additions & 6 deletions Classes/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ import SwiftyJSON


public class Client {
let baseURL: String
public let rootURL: String
var apiBaseURL: String { return "\(rootURL)/api/v1" }
let apiKey: String?

public convenience init(apiKey: String?) {
self.init(baseURL: "https://asakusa-satellite.herokuapp.com/api/v1", apiKey: apiKey)
self.init(rootURL: "https://asakusa-satellite.herokuapp.com", apiKey: apiKey)
}

public init(baseURL: String, apiKey: String?) {
self.baseURL = baseURL
public init(rootURL: String, apiKey: String?) {
self.rootURL = rootURL
self.apiKey = apiKey

// remove all AasakusaSatellite cookies
Expand All @@ -30,7 +31,7 @@ public class Client {

private func removeCookies() {
let cs = NSHTTPCookieStorage.sharedHTTPCookieStorage()
for cookie in (cs.cookiesForURL(NSURL(string: baseURL)!) as? [NSHTTPCookie]) ?? [] {
for cookie in (cs.cookiesForURL(NSURL(string: rootURL)!) as? [NSHTTPCookie]) ?? [] {
cs.deleteCookie(cookie)
}
}
Expand Down Expand Up @@ -74,7 +75,7 @@ public class Client {
// MARK: -

private func request<T: ResponseItem>(endpoint: Endpoint, completion: Response<T> -> Void) {
Alamofire.request(endpoint.URLRequest(baseURL, apiKey: apiKey)).responseJSON { (request, response, object, error) -> Void in
Alamofire.request(endpoint.URLRequest(apiBaseURL, apiKey: apiKey)).responseJSON { (request, response, object, error) -> Void in
if object == nil || error != nil {
NSLog("failure in Client.request(\(endpoint)): \(error)")
completion(.Failure(error))
Expand Down
114 changes: 114 additions & 0 deletions Classes/ios/TwitterAuthViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//
// TwitterAuthViewController.swift
// AsakusaSatelliteSwiftClient
//
// Created by BAN Jun on 2015/03/15.
// Copyright (c) 2015年 codefirst. All rights reserved.
//

import Foundation
import UIKit


private let kAuthTwitterPath = "/auth/twitter"
private let kAccountPath = "/account"


public class TwitterAuthViewController: UIViewController, UIWebViewDelegate {
let webview = UIWebView(frame: CGRectZero)
let rootURL: NSURL
let completion: (String? -> Void)

// MARK: init

public init(rootURL: NSURL, completion: (String? -> Void)) {
self.rootURL = rootURL
self.completion = completion
super.init(nibName: nil, bundle: nil)
}

required public init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: -

public override func viewDidLoad() {
title = NSLocalizedString("Sign in with Twitter", comment: "")

webview.autoresizingMask = .FlexibleWidth | .FlexibleHeight
webview.frame = view.bounds
webview.delegate = self
view.addSubview(webview)

if let url = NSURL(string: kAuthTwitterPath, relativeToURL: rootURL) {
// load /auth/twitter with referer /account
// oauth callback redirects to referer
let request = NSMutableURLRequest(URL: url)
request.setValue(kAccountPath, forHTTPHeaderField: "Referer")
webview.loadRequest(request)
} else {
let ac = UIAlertController(
title: NSLocalizedString("Cannot Load", comment: ""),
message: NSLocalizedString("Invalid URL: ", comment: "") + "\(rootURL)",
preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: { _ in
ac.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(ac, animated: true, completion: nil)
}
}

// MARK: UIWebViewDelegate

private func isRedirectedBackToAsakusaSatellite(request: NSURLRequest) -> Bool {
let reqURLString = request.URL.absoluteString
let rootURLString = rootURL.absoluteString!

return reqURLString?.hasPrefix(rootURLString) == true && request.URL.path == kAccountPath
}

public func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if isRedirectedBackToAsakusaSatellite(request) {
// TODO: display HUD
NSLog("Getting API Key...")
}
return true
}

public func webViewDidStartLoad(webView: UIWebView) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
}

public func webViewDidFinishLoad(webView: UIWebView) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = false

if isRedirectedBackToAsakusaSatellite(webview.request!) {
// did load /account on AsakusaSatellite
// TODO: display HUD
NSLog("Completed")

// get apiKey from text field
let js = "$('#account_secret_key').attr('value')"
let apiKey = webview.stringByEvaluatingJavaScriptFromString(js)

webView.delegate = nil // unlink delegate before removing self
navigationController?.popViewControllerAnimated(true)
completion((apiKey?.isEmpty ?? true) ? nil : apiKey)
}
}

public func webView(webView: UIWebView, didFailLoadWithError error: NSError) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = false

let ac = UIAlertController(
title: NSLocalizedString("Cannot Load", comment: ""),
message: error.localizedDescription,
preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: { _ in
ac.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(ac, animated: true, completion: nil)
}
}

19 changes: 18 additions & 1 deletion Example/AsakusaSatelliteSwiftClientExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class ViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate
listButton.addTarget(self, action: "list:", forControlEvents: .TouchUpInside)
messagesTextView.delegate = self

navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Sign in", style: .Plain, target: self, action: "signin:")

let views = [
"apiKey": apiKeyField,
"name": usernameLabel,
Expand Down Expand Up @@ -82,7 +84,7 @@ class ViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate
let apiKey = NSUserDefaults.standardUserDefaults().objectForKey(kDefaultsKeyApiKey) as? String
apiKeyField.text = apiKey
client = AsakusaSatellite.Client(apiKey: apiKey)
// client = AsakusaSatellite.Client(baseURL: "http://localhost:3000/api/v1", apiKey: apiKey)
// client = AsakusaSatellite.Client(rootURL: "http://localhost:3000", apiKey: apiKey)
NSLog("initialized client with apiKey = \(apiKey)")

usernameLabel.text = "(initialized)"
Expand Down Expand Up @@ -144,6 +146,21 @@ class ViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate
}
}

func signin(sender: AnyObject?) {
let vc = TwitterAuthViewController(rootURL: NSURL(string: client.rootURL)!) { [weak self] apiKey in
let defaults = NSUserDefaults.standardUserDefaults()
if let apiKey = apiKey {
defaults.setObject(apiKey, forKey: kDefaultsKeyApiKey)
} else {
NSLog("cannot sign in")
defaults.removeObjectForKey(kDefaultsKeyApiKey)
}
defaults.synchronize()
self?.reloadClient()
}
navigationController?.pushViewController(vc, animated: true)
}

// MARK: - TextField

func textFieldShouldReturn(textField: UITextField) -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Alamofire: 524225da382071ee3e6d0badd0ee4b4dc36740de
AsakusaSatellite: e7082b74b819a4436ccb0efa522ed93e94406b74
AsakusaSatellite: 499c3117a42e276856fbd04608e38d40718b1c71
Socket.IO-Client-Swift: 23d9f0db0cdcb98623486ddf0ee811b158e9cd02
SwiftyJSON: 48be7490a3989a58a3f511cd54167f0a2b466e76

Expand Down

0 comments on commit edb140d

Please sign in to comment.