Last active
December 1, 2016 19:29
LINE Notify を iOS から使ってみる
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.swift | |
// | |
import UIKit | |
class ViewController: UIViewController { | |
typealias VC = ViewController | |
private static let MyHost = "https://example.com" | |
private static let BotHost = "https://notify-bot.line.me" | |
private static let ApiHost = "https://notify-api.line.me" | |
private static let TokenPath = "/oauth/token" | |
private static let GrantType = "authorization_code" | |
private static let RedirectUri = "\(MyHost)/callback/" | |
private static let ClientId = "YourClientId" | |
private static let ClientSecret = "YourClientSecret" | |
private static let GetAccessTokenUrlFormat = "\(VC.BotHost)\(VC.TokenPath)?grant_type=\(VC.GrantType)&code=%@&redirect_uri=\(VC.RedirectUri)&client_id=\(VC.ClientId)&client_secret=\(VC.ClientSecret)" | |
private static let NotifyPath = "/api/notify" | |
private static let PostMessageUrlFormat = "\(VC.ApiHost)\(VC.NotifyPath)?message=%@" | |
@IBOutlet weak var button: PrimaryButton! | |
private var accessToken: String? = nil { | |
didSet { | |
let title = accessToken == nil ? "WebViewを開く" : "テストメッセージ送信" | |
button.setTitle(title, for: .normal) | |
} | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
title = "Gome" | |
accessToken = UserDefaults.standard.string(forKey: "AccessToken") | |
} | |
/** | |
ボタンタップ | |
*/ | |
@IBAction func didTapButton(_ sender: Any) { | |
if let accessToken = accessToken { | |
presentPostMessageAlert(accessToken) | |
} else { | |
openWebView() | |
} | |
} | |
/** | |
WebViewを開く | |
*/ | |
private func openWebView() { | |
let webVC = WebViewController(VC.MyHost) { [weak self] url, vc in | |
guard url.contains(VC.RedirectUri + "?code=") else { return } | |
vc.dismissViewController() | |
guard let comp = NSURLComponents(string: url) else { return } | |
let c = comp.queryItems?.filter { $0.name == "code" }.first?.value | |
guard let code = c else { NSLog("code is nil."); return } | |
self?.getAccessToken(code) { token in | |
guard let token = token else { NSLog("token is nil."); return } | |
self?.presentAlertViewController("アクセストークンの取得に成功しました。") | |
self?.accessToken = token | |
UserDefaults.standard.set(token, forKey: "AccessToken") | |
} | |
} | |
present(webVC.withNavigationController(true, "Login"), animated: true, completion: nil) | |
} | |
/** | |
メッセージ送信用アラートを表示 | |
*/ | |
private func presentPostMessageAlert(_ accessToken: String) { | |
presentAlertViewController("メッセージを送信します。", nil, okHandler: { [weak self] textFiled in | |
guard let message = textFiled?.text else { | |
self?.presentErrorAlertViewController("メッセージが入力されていません") | |
return | |
} | |
guard let msg = message.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) else { | |
return | |
} | |
self?.postMessage(accessToken, msg) { [weak self] e in e == nil ? self?.presentAlertViewController("メッセージの送信に成功") : NSLog("error=\(e)") } | |
}) | |
} | |
/** | |
AccessToken を取得します | |
*/ | |
private func getAccessToken(_ code: String, _ callback: @escaping ((String?) -> ())) { | |
let url = NSString(format: VC.GetAccessTokenUrlFormat as NSString, code) as String | |
post(url, nil) { d, r, e in | |
if let e = e { NSLog("error=\(e)"); callback(nil); return } | |
guard let d = d else { callback(nil); return } | |
let result = NSString(data: d, encoding: String.Encoding.utf8.rawValue)! | |
NSLog("result=\(result)") | |
guard let data = result.data(using: String.Encoding.utf8.rawValue) else { callback(nil); return } | |
guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { callback(nil); return } | |
guard let accessToken = json?["access_token"] as? String else { NSLog("access_token is nil."); callback(nil); return } | |
callback(accessToken) | |
} | |
} | |
/** | |
Message を送信します | |
*/ | |
private func postMessage(_ accessToken: String, _ message: String, callback: @escaping (Error?) -> ()) { | |
let url = NSString(format: VC.PostMessageUrlFormat as NSString, message) as String | |
let header = ["Authorization": "Bearer \(accessToken)"] | |
post(url, header) { d, r, e in | |
print("d=\(d), e=\(e), e=\(e)") | |
callback(e) | |
} | |
} | |
/** | |
POST リクエストを送信します | |
*/ | |
private func post(_ url: String, _ headers: [String: String]?, completionHandler: @escaping (Data?, URLResponse?, Error?) -> ()) { | |
let request = NSMutableURLRequest(url: URL(string: url)!) | |
headers?.forEach { request.addValue($0.value, forHTTPHeaderField: $0.key) } | |
request.httpMethod = "POST" | |
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, responce, error in | |
DispatchQueue.main.async() { completionHandler(data, responce, error) } | |
} | |
task.resume() | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment