SwiftでNSURLConnectionを使ってHTMLを取得
Swift使ってHTML取得してみました。
Objective-Cに比べてすげー楽にすらすら書ける気がする。。。
NSURLConnectionを使用して非同期通信
NSURLConnectionに用意されているプロトコルを使って実装します。
// サーバからレスポンスを受け取ったときのデリゲート func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) { } // サーバからデータが送られてきたときのデリゲート func connection(connection: NSURLConnection!, didReceiveData data: NSData!){ } // データロードが完了したときのデリゲート func connectionDidFinishLoading(connection: NSURLConnection!){ }
これらのメソッドを実装するだけです。
Objective-Cとなんら変わらない。
ソースコードの全貌
ということで今回書いたコードは以下のとおり。
単純にURL指定してURLをコンソールに出力。
画面にはsuccessと表示するだけです。
ViewController.swift
import UIKit class ViewController: UIViewController, ConnectionResult { // プロトコルを継承する // !マークは値が必ず入っていることが保証されるOptional型 // 値が入っていないとエラーになる // この場合はStroyboardからひもづけているので必ずついていなければならない // reference outlet@storyboard @IBOutlet var label: UILabel! var connection : Connection! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // touch up inside@storyboard @IBAction func btnClick(sender: AnyObject) { // インスタンス化とデリゲートのセット connection = Connection(urlStr: "ここにURL") connection.delegate = self connection.doConnect() } // delegate // 実際に処理を行う func showResult(resultMessage: String?) -> Void { label.text = resultMessage } }
Connection.swift
import Foundation // プロトコル protocol ConnectionResult{ func showResult(resultMessage: String?) -> Void } public class Connection : NSObject{ // 参考: // NSURLConnection ttp://stackoverflow.com/questions/24176362/ios-swift-and-nsurlconnection // Delegate, Protocol ttp://qiita.com/mochizukikotaro/items/a5bc60d92aa2d6fe52ca // nilが入ってるなんてあり得ない! var urlStr : String var data : NSMutableData? = nil var delegate : ConnectionResult! // コンストラクタ public init(urlStr: String) { self.data = NSMutableData() self.urlStr = urlStr } // アクセス public func doConnect() -> Void{ var url : NSURL = NSURL(string: urlStr) // キャッシュを無視 var request : NSURLRequest = NSURLRequest(URL: url, cachePolicy:NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 60.0) var connect : NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true) // 接続開始 connect.start() } // サーバからレスポンスを受け取ったときのデリゲート func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) { // Recieved a new request, clear out the data object self.data! = NSMutableData() } // サーバからデータが送られてきたときのデリゲート func connection(connection: NSURLConnection!, didReceiveData data: NSData!){ self.data!.appendData(data) } // データロードが完了したときのデリゲート func connectionDidFinishLoading(connection: NSURLConnection!){ // バイナリデータが発行される let html : String = NSString(data: self.data!, encoding: NSUTF8StringEncoding) // コンソールに出力 println(html) // 処理を呼び出すだけ self.delegate.showResult("success!") } }
DelegateとProtocolとを独自に実装。
これらについても忘れそうなのでそのうち残しておこう。
アクセス修飾子についての理解も甘い、CocoaとかFoundationとかは全publicじゃないとだめなのかな?
デリゲートメソッドprivateで定義したらだめだった。
githubにもあげました。
https://github.com/kaisou4537/swiftstudy/tree/master/swift_4/ConnectionTest