Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active June 17, 2018 14:29
Show Gist options
  • Save KentarouKanno/6461193dd508659c9f36 to your computer and use it in GitHub Desktop.
Save KentarouKanno/6461193dd508659c9f36 to your computer and use it in GitHub Desktop.
NSURLSession1

NSURLSession1

URLセッションのライフサイクル

サンプルAPI: heartrails.com

★ ATSを無効にする

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
// 非同期通信

if let url = URL(string: "http://www.apple.com") {
    let request = URLRequest(url: url)
    let session = URLSession.shared
    
    let task = session.dataTask(with: request) { data, response, error in
        
        // サブスレッドで実行される
        if let _ = response, let data = data {
            
            print(NSString(data: data, encoding: String.Encoding.utf8.rawValue) ?? "")
            
            
        } else {
            print(error ?? "")
        }
    }
    
    task.resume()
}
// ------------------------


let url = NSURL(string: "http://www.apple.com")!
let request = NSMutableURLRequest(URL: url)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: NSOperationQueue.mainQueue())

let task = session.dataTaskWithRequest(request) { data, response, error in
    
    // メインスレッドで実行される
    if let response = response, data = data {
        
        print(NSThread.isMainThread())
        print(NSString(data: data, encoding: NSUTF8StringEncoding))
        
        
    } else {
        print(error)
    }
}

task.resume()

★ Swift3

let url = URL(string: "http://www.apple.com")!
let request = URLRequest(url: url)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: nil, delegateQueue: OperationQueue.main)

let task = session.dataTask(with: request) { data, response, error in
    
    // メインスレッドで実行される
    if let _ = response, let data = data {
        
        print(NSString(data: data, encoding: String.Encoding.utf8.rawValue))
        
        do {
                    
            let jsonDic = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSDictionary
                    
        } catch {
                    
        }
        
    } else {
        print(error)
    }
}

task.resume()


// URLでの書き方

let url: URL = URL(string: "http://www.apple.com")!
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
    if error != nil {
        
        print(error!.localizedDescription)
    } else {
        
        print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue))
    }
})
task.resume()

★ 通信キャッシュを設定する
参考URL : iOSにおける通信キャッシュについて

let url = NSURL(string: "URL")
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue())
let request = NSMutableURLRequest(URL: url!)
request.cachePolicy = .ReturnCacheDataElseLoad
request.timeoutInterval = 30

/*
NSURLRequestCachePolicy

UseProtocolCachePolicy
ReloadIgnoringLocalCacheData
ReloadIgnoringLocalAndRemoteCacheData // Unimplemented
ReloadIgnoringCacheData
    
case ReturnCacheDataElseLoad
case ReturnCacheDataDontLoad
    
case ReloadRevalidatingCacheData // Unimplemented
*/
設定 内容 キャッシュ
UseProtocolCachePolicy プロトコルの規約に従う(デフォルト) 使う
ReloadIgnoringLocalCacheData キャッシュを使わない 使わない
ReloadIgnoringLocalAndRemoteCacheData 未実装
ReloadIgnoringCacheData NSURLRequestReloadIgnoringLocalCacheDataと同じ
ReturnCacheDataElseLoad キャッシュがある場合はキャッシュを使い、無い場合は通信する 使う
ReturnCacheDataDontLoad 常にキャッシュを使い、キャッシュがなければエラーになる 使う
ReloadRevalidatingCacheData 未実装 -

★ POST Image (Closure)

import UIKit

class ViewController: UIViewController, NSURLSessionTaskDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let image = UIImage(named: "swift")!
        
        let url = NSURL(string: "http://www.kentar0u.sakura.ne.jp/upload.php")!
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        
        let imageData = UIImageJPEGRepresentation(image, 1.0)!
        
        let session = NSURLSession.sharedSession()
        let tasK = session.uploadTaskWithRequest(request, fromData: imageData) { (data, response, error) in
            
            if let error = error {
                print(error.description)
            }
        }
        
        tasK.resume()
    }
}

upload.php

<?php
$image = file_get_contents("php://input");
file_put_contents('dl.png',$image);
?>

★ POST Image (Delegate)
uploadTaskWithRequestにImageDataを渡す場合

import UIKit

class ViewController: UIViewController, URLSessionTaskDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // UIImage → NSData
        let image = UIImage(named: "swift")!
        
        guard let imageData = image.jpegData(compressionQuality: 1.0) else { return }
        
        let myCofig: URLSessionConfiguration = URLSessionConfiguration.default
        
        let myUrl: URL = URL(string: "http://www.kentar0u.sakura.ne.jp/upload.php")!
        
        var myRequest: URLRequest = URLRequest(url: myUrl)
        myRequest.httpMethod = "POST"
        
        let session = URLSession(configuration: myCofig, delegate: self, delegateQueue: OperationQueue.main)
        
        let task = session.uploadTask(with: myRequest, from: imageData)
        task.resume()
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
        print("willPerformHTTPRedirection")
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
        print("didSendBodyData")
    }
    
    // Connection Finish
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        print("didCompleteWithError")
        if let error = error {
            print((error as NSError).code)
        }
    }
}

★ POST Image (Delegate)
HTTPBodyにImageDataを渡す場合

import UIKit

class ViewController: UIViewController, URLSessionTaskDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // UIImage → NSData
        let image = UIImage(named: "swift")!
        
        guard let imageData = image.jpegData(compressionQuality: 1.0) else { return }
        
        let myCofig: URLSessionConfiguration = URLSessionConfiguration.default
        
        let myUrl: URL = URL(string: "http://www.kentar0u.sakura.ne.jp/upload.php")!
        
        var myRequest: URLRequest = URLRequest(url: myUrl)
        myRequest.httpMethod = "POST"
        myRequest.httpBody = imageData
        
        let session = URLSession(configuration: myCofig, delegate: self, delegateQueue: OperationQueue.main)
        let task = session.uploadTask(withStreamedRequest: myRequest)
        task.resume()
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
        print("willPerformHTTPRedirection")
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
        print("didSendBodyData")
    }
    
    // Connection Finish
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        print("didCompleteWithError")
        if let error = error {
            print((error as NSError).code)
        }
    }
}

★ POST JSON

import UIKit

class ViewController: UIViewController, NSURLSessionTaskDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let url = NSURL(string: "http://localhost:80/upload.php")!
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        let params: [String: AnyObject] = [
            "foo": "bar",
            "baz": [
                "a": 1,
                "b": 20,
                "c": 300
            ]
        ]
        request.HTTPBody = (try? NSJSONSerialization.dataWithJSONObject(params, options: []))
    
        let session = NSURLSession.sharedSession()
        let tasK = session.dataTaskWithRequest(request){ (data, response, error) in
            
            print((response as! NSHTTPURLResponse).allHeaderFields)
            print(NSString(data: data!, encoding: NSUTF8StringEncoding))
            
            if let error = error {
                print(error.description)
            }
        }
        tasK.resume()
    }
}

upload.php

<?php
$json_string = file_get_contents('php://input'); 

echo $json_string;
$obj = json_decode($json_string);
var_dump($obj);
?>

★ POST Parameters

import UIKit

class ViewController: UIViewController, NSURLSessionTaskDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let url = NSURL(string: "http://localhost:80/upload.php")!
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        
        let str = "data=123&name=kentarou&last=kanno"
        let strData = str.dataUsingEncoding(NSUTF8StringEncoding)
        request.HTTPBody = strData
        
        let session = NSURLSession.sharedSession()
        let tasK = session.dataTaskWithRequest(request){ (data, response, error) in
            
            print((response as! NSHTTPURLResponse).allHeaderFields)
            print(NSString(data: data!, encoding: NSUTF8StringEncoding))
            
            if let error = error {
                print(error.description)
            }
        }
        tasK.resume()
    }
}

upload.php

<?php
echo json_encode([
"data1" => $_POST["data"],
"data2" => $_POST["last"],
"data3" => $_POST["name"]
]);
?>

Sample

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let url = URL(string: "https://www.googleapis.com/books/v1/volumes?q=isbn:9784839953539")!
        let request = NSMutableURLRequest(url: url)
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config, delegate: nil, delegateQueue: OperationQueue.main)
        
        let task = session.dataTask(with: request as URLRequest) { data, response, error in
            
            // メインスレッドで実行される
            if let _ = response, let data = data {
                
                do {
                    
                    let jsonDic = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSDictionary
                    
                    let arrayData = jsonDic["items"] as? NSArray
                    let dict1 = arrayData![0] as? NSDictionary
                    let dict2 = dict1!["volumeInfo"] as? NSDictionary
                    let dict3 = dict2!["title"] as? String
                    print(dict3 ?? "")
                    
                } catch {
                    
                }
                
                print(Thread.isMainThread)
                print(NSString(data: data, encoding: String.Encoding.utf8.rawValue) ?? "")
                
                
            } else {
                print(error ?? "")
            }
        }
        
        task.resume()
    }
}

s

JSON

{
 "kind": "books#volumes",
 "totalItems": 1,
 "items": [
  {
   "kind": "books#volume",
   "id": "BXYVBQAAQBAJ",
   "etag": "mncCpMSrfLc",
   "selfLink": "https://www.googleapis.com/books/v1/volumes/BXYVBQAAQBAJ",
   "volumeInfo": {
    "title": "Swiftではじめる iPhoneアプリ開発の教科書 【iOS 8&Xcode 6対応】",
    "subtitle": "",
    "authors": [
     "森巧尚"
    ],
    "publisher": "マイナビ出版",
    "publishedDate": "2014-10-31",
    "description": "新しいプログラム言語Swiftで、iPhoneアプリ開発をはじめよう! 2014年のWorldwide Developers Conference(WWDC)で、Appleから新しいプログラミング言語の「Swift言語」が発表されました。本書はiOS 8&Xcode 6の環境で、Swift言語を使ってiPhoneアプリを作っていく入門書です。今回登場したSwiftは、速くて、モダンで、安全な言語です。シンプルで分かりやすいので、iPhoneアプリの入門者にとっても、非常に取り組みやすいでしょう。そしてXcodeも、もともと「より多くの人にiPhoneアプリを作って欲しい」という目的で生まれ、成長してきたアプリです。作り始めるときにはテンプレートを用意してくれますし、アプリの画面をデザインするときには、見たまま作れるエディターを出してくれます。プログラムを入力しているときには、プログラムの続きを推測して教えてくれます。Xcodeを使いこなすことができれば、アプリ作りは快適に、楽しいものになるでしょう。本書の特徴の1つ目は「Xcodeの操作を丁寧に、できる限り分かりやすく説明している」、ということです。プログラミング初心者の方にもわかりやすく進めていただけるよう、図版や図解も豊富に盛り込んでいます。また、項目ごとに3〜5分で作成できる短めのサンプルを用意しています。その作成手順を省略せずに解説していますので、本書を読みながら、ぜひサンプルを一緒に作ってみてください。読みながら、手を動かし、モノを完成させていくことで、「iPhoneアプリの作り方」を基本から身につけることができるでしょう。もう一つの本書の特徴は、作り方だけでなく、「アプリを設計する考え方」も解説しているということです。アプリを作っていくときには「プログラムの文法」だけでなく「アプリを設計する考え方」が重要です。本書では「ビューコントローラー」「デリゲート」「AutoLayout」「Optional Value」など、開発時に重要な、でも難しそうに思える考え方をやさしく解説していきます。これらは難しそうに見えますが、実は「どう使うのか」さえ理解すれば「わかりやすい考え方」なのです。この考え方に沿ってアプリを設計していくと、自然に作りやすくなっていくでしょう。さらに、知っていればきっと役立つTipsやワンポイントコラムも多数ちりばめてあります。必要に応じて、ぜひコラムを読んでみてください。よりスキルアップするヒントを得られることと思います。本書を使って、ぜひ楽しみながら、iPhoneアプリ開発とSwiftを攻略していってください! 【注意】電子版をiOS 8.1/Xcode 6.1.1/Swift 1.1に対応した「v2.1」に更新しました。Xcode 6.1.1での変更箇所には、[Xcode 6.1.1]アイコンを付けています。また、サポートサイトには、Xcode 6.0用とXcode 6.1用、それぞれのサンプルファイルを用意してあります。(2015/1/23)",
    "industryIdentifiers": [
     {
      "type": "ISBN_13",
      "identifier": "9784839953539"
     },
     {
      "type": "ISBN_10",
      "identifier": "4839953538"
     }
    ],
    "readingModes": {
     "text": false,
     "image": false
    },
    "pageCount": 460,
    "printType": "BOOK",
    "categories": [
     "Technology & Engineering"
    ],
    "maturityRating": "NOT_MATURE",
    "allowAnonLogging": false,
    "contentVersion": "0.2.0.0.preview.0",
    "imageLinks": {
     "smallThumbnail": "http://books.google.co.jp/books/content?id=BXYVBQAAQBAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
     "thumbnail": "http://books.google.co.jp/books/content?id=BXYVBQAAQBAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
    },
    "language": "ja",
    "previewLink": "http://books.google.co.jp/books?id=BXYVBQAAQBAJ&dq=isbn:9784839953539&hl=&cd=1&source=gbs_api",
    "infoLink": "http://books.google.co.jp/books?id=BXYVBQAAQBAJ&dq=isbn:9784839953539&hl=&source=gbs_api",
    "canonicalVolumeLink": "http://books.google.co.jp/books/about/Swift%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B_iPhone%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B.html?hl=&id=BXYVBQAAQBAJ"
   },
   "saleInfo": {
    "country": "JP",
    "saleability": "NOT_FOR_SALE",
    "isEbook": false
   },
   "accessInfo": {
    "country": "JP",
    "viewability": "NO_PAGES",
    "embeddable": false,
    "publicDomain": false,
    "textToSpeechPermission": "ALLOWED",
    "epub": {
     "isAvailable": false
    },
    "pdf": {
     "isAvailable": true
    },
    "webReaderLink": "http://books.google.co.jp/books/reader?id=BXYVBQAAQBAJ&hl=&printsec=frontcover&output=reader&source=gbs_api",
    "accessViewStatus": "NONE",
    "quoteSharingAllowed": false
   },
   "searchInfo": {
    "textSnippet": "新しいプログラム言語Swiftで、iPhoneアプリ開発をはじめよう! 2014年のWorldwide Developers Conference(WWDC)で、Appleから新しいプログラミング言語の「Swift言語」が発表されました。本 ..."
   }
  }
 ]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment