↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > NSURLConnectionでHTTPやFTP通信する

NSURLConnectionでHTTPやFTPアクセス

サンプル画像

今回はiPhoneとサーバ間でHTTPやFTPプロトコル通信を行うNSURLConnectionの説明

NSURLConnectionのクラス階層

NSObject

NSURLConnection

参考:001 NSURLConnectionを用いたHTTP通信(非同期)
参考:SwiftでWebAPIアプリを作った時の要点
参考:SwiftでNSURLConnectionを使ってHTMLを取得
参考:Foundation Framework Reference NSURLConnection Class Reference

やってみた

swift-salaryman.comサーバに置いたnsurlconnection_sayhello.phpにHTTP通信でアクセスして戻り値を表示します。(非同期)


import UIKit

class ViewController: UIViewController {
    
    var myTextView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var myUrl:NSURL = NSURL(string:"http://swift-salaryman.com/nsurlconnection_sayhello.php")!
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        var myData:NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        println(myData)//Hello! Hello! I am from server of swift-salaryman.com!!
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

nsurlconnection_sayhello.phpの中身


<?php
 echo "Hello! Hello! I am from server of swift-salaryman.com!!";
?>

この文字列が上記サンプルを実行すると表示されます


同期させたい場合

sendAsynchronousRequestをsendSynchronousRequestに変更します。


import UIKit

class ViewController: UIViewController {
    
    var myTextView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var myUrl:NSURL = NSURL(string:"http://swift-salaryman.com/nsurlconnection_sayhello.php")!
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        var response = NSURLConnection.sendSynchronousRequest(myRequest, returningResponse: nil, error:nil)
        println(response)//Hello! Hello! I am from server of swift-salaryman.com!!
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


POSTしたい場合

リクエストを投げるスクリプトにPOSTでデータを渡す場合は以下のように調整します。


import UIKit

class ViewController: UIViewController {
    
    var myTextView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var myUrl:NSURL = NSURL(string:"http://swift-salaryman.com/nsurlconnection_sayhello.php")!
        var myRequest:NSMutableURLRequest  = NSMutableURLRequest(URL: myUrl)
        
        let str = "name=swift-salaryman&pw=jitsuwahagetenaihigedage"
        let strData = str.dataUsingEncoding(NSUTF8StringEncoding)
        myRequest.HTTPMethod = "POST"
        myRequest.HTTPBody = strData
        
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        var myData:NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        println(myData)//Hello! Hello! I am from server of swift-salaryman.com!!
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

JSONをPOSTしたい場合

JSONをPOSTしてPHPで処理した場合の方法を記載しておきます。


import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var myUrl:NSURL = NSURL(string:"http://swift-salaryman.com/nsurlconnection_sayhello_post.php")!
        var myRequest:NSMutableURLRequest  = NSMutableURLRequest(URL: myUrl)
        
        myRequest.HTTPMethod = "POST"
        
        //JSON
        myRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
        var params: [String: AnyObject] = [
            "type": "swift",
            "man": [
                "age": 33,
                "location": "Osaka",
                "lang": "ja"
            ]
        ]
        myRequest.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: nil)
       
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        var myData:NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        println(myData)//Hello! Hello! I am from server of swift-salaryman.com!!
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

nsurlconnection_sayhello_post.phpの中身


<?php

$json_string = file_get_contents('php://input');
echo $json_string;
$obj = json_decode($json_string);
var_dump();

echo "Hello! Hello! I am from server of swift-salaryman.com!!";
print $obj->man->location;
?>?>

↓出力結果


{"man":{"location":"Osaka","age":33,"lang":"ja"},"type":"swift"}object(stdClass)#1 (2) {
  ["man"]=>
  object(stdClass)#2 (3) {
    ["location"]=>
    string(5) "Osaka"
    ["age"]=>
    int(33)
    ["lang"]=>
    string(2) "ja"
  }
  ["type"]=>
  string(5) "swift"
}
Hello! Hello! I am from server of swift-salaryman.com!osaka!

上記よりサーバで正しく受け取っていることがわかります。$_POSTだと無理なのですね、、、、しりませんでした。 サーバ側で $obj->man->locationでアクセスすれば特定の値を取得することができます。

参考:SwiftでHTTPリクエストする
参考:PHPでHTTP POSTされたJSON本文を受け取る方法

カスタマイズ

FTP,HTTP,HTTPS,FILEに対応しているとのことですのでFTPでログインする検証を行ってみます

参考:認証が必要なFTPのクライアントを作るときの注意点(例:iPhone SDK)
参考:NSURLConnection FTP file upload
参考:[objective-c]FTP通信でのモード切り替えについて
参考:Implementing SimpleFTPSample in swift

これらを読んでいるとFTPでの簡単な通信はNSURLConnectionで可能ですが、ファイルアップロード等する場合は Objective-Cで作成されているLibarryのCFFTPStreamを利用してSwiftから実行するべきだそうです。このCFFTPStreamは別記事にて 調査してみたいと思います!まずはNSURLConnectionで簡単なFTP通信でログインまでを実施してみます。

注意:FTPサーバアカウントやパスワードを仮のものに変えていますので、該当名に切り替えてください


import UIKit

class ViewController: UIViewController {
    
    var myTextView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var myUrl:NSURL = NSURL(string:"ftp://swiftsalaryman.com")!
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        var myData:NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        println(myData)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


{NSUnderlyingError=0x7ffda95c7b20 "You do not have permission to access the requested resource.", 
NSErrorFailingURLStringKey=ftp://swiftsalaryman.com, 
NSErrorFailingURLKey=ftp://swiftsalaryman.com, 
NSLocalizedDescription=You do not have permission to access the requested resource.}

これだとエラーで怒られました。

パスワードとアカウントを追加して再トライ!
ftp://[アカウント名]:[パスワード]@swiftsalaryman.com



import UIKit

class ViewController: UIViewController {
    
    var myTextView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var myUrl:NSURL = NSURL(string:"ftp://swiftsalaryman:hogehogepassword@swiftsalaryman.com")!
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        var myData:NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        println(myData)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


drwx---r-x  10 swiftsalaryman users         512 Jan 27 13:20 .
drwxr-xr-x  89 root     wheel        3072 Feb  3 20:19 ..
-rw-r--r--   1 swiftsalaryman users         773 Jan  7  2009 .cshrc
-rw-r--r--   1 swiftsalaryman users         258 Jan  2  2009 .login
-rw-r--r--   1 swiftsalaryman users         167 Jan  2  2009 .login_conf
-rw-r--r--   1 swiftsalaryman users           3 Dec 18  2013 .my.version
-rw-r--r--   1 swiftsalaryman users         762 Jan  7  2009 .profile
-rw-r--r--   1 swiftsalaryman users         980 Jan  2  2009 .shrc
drwx------   2 swiftsalaryman users         512 Mar 13  2009 .spamassassin
drwx------   2 swiftsalaryman users         512 Mar 13  2009 .ssh
drwx------   3 swiftsalaryman users         512 Mar 13  2009 MailBox
drwx------   3 swiftsalaryman users         512 Oct 27 07:36 db
drwx------  11 swiftsalaryman users         512 Oct 27 07:38 ports
drwxr-xr-x   2 swiftsalaryman users         512 Jan 27 13:20 sakura_pocket
drwxr-xr-x   2 swiftsalaryman users         512 Mar 13  2009 sblo_files
drwxr-xr-x  10 swiftsalaryman users         512 Jan 20 23:12 www

初期ディレクトリのフォルダツリー表示を取得できました!

まとめ

単純なHTTP通信であれば簡単に実装できる便利なクラスでした。ただしバックグラウンドで大きなサイズのファイルダウンロードしたい場合等は NSURLSessionを利用すると良い様です。過去記事に記載していますのでよろしければこちらからどうぞ!

↓こんな記事もありますよ!


2021-05-14 14:21:41

WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。

AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、 昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は...

2021-05-06 14:04:37

LINEのアニメーションスタンプ制作の落とし穴、、、失敗談

ゴールデンウィークにLINEスタンプを作成してみました。 作り切って申請も通したんですが、意図したアニメーションと違う、、、、 LINEクリエーターの画面だと、アニメーションのプレビュー...

2021-05-01 18:05:35

久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。

忘れないようにメモ エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。 ターゲット→ex...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!