見出し画像

Swiftでいこう! - "Combine" - URLSession

こちらの動画をみながらやっていきます。いよいよ本格的な使い方となっているようです。

まず必要なフレームワークをインポート、Combineを忘れずに。

import SwiftUI
import Combine

URLからAPI、Jsonを取ってきます。まず、取り出すデータの構造体を作って、"Codable"に準拠させます。(構造体の名前は動画の名前と変更しています)

struct TestData:Codable{
   let title:String
   let description:Description
}

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

Jsonを"Codable"を使ってデータを使えるようにします。そして使えるようにデータを整形する命令も用意して起きます。

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

ISO8601は、時刻フォーマットに関する国際標準のフォーマットで、APIやログ出力などで一般的に使用されています。

それでは次に必要なAPI通信の必要なコードを書いていきます。​

ここで一つ問題があります。紹介動画ではライブドアの天気情報が取得できるAPIを使ってるのですが、このサービスは実は終わってしまっています。以前"Swiftで行こう!--JSONの取扱"で使わせていただいたJSONデータを利用させていただきました。

URLを指定してデータを取り出していきます。まず、アドレスの取得です。

let url = URL(string: "https://pythonchannel.com/media/codecamp/201902/JSON-Sample1.json")!

let request =  URLRequest(url: url)

そして、データを実際に取り出します。ここでメインテーマの"Combine"を使うことになります。

単純にすれば

URLSession.shared.dataTaskPublisher ・・・ 
.sink(receiveCompletion:)

この2つのコードに集約されます。

実際のコードです。

let cancellable = URLSession.shared.dataTaskPublisher(for: request)
   .map({(data, res) in
       return data
   })
   .decode(type: TestData.self, decoder: decoder)
   .sink(receiveCompletion: {completion in
           switch completion{
           case .failure(let error):
               print(error.localizedDescription)
           case .finished:
               print("終了")
           }
   }
   , receiveValue: {weather in
       print(weather.name)
       print(weather.link)
       
   })

このコードでPublisherは、

let cancellable = URLSession.shared.dataTaskPublisher(for: request)
.map({(data, res) in
return data
})
.decode(type: TastData.self, decoder: decoder)

.map、.decodeはOperatorでデータを使えるように変換します。

そして次にデータを受けて処理していくパートとなります。

.sink(receiveCompletion: {completion in
 switch completion{
  case .failure(let error):
   print(error.localizedDescription)
  case .finished:
   print("終了")
  }
}
, receiveValue: {weather in
 print(weather.name)
 print(weather.link)
})

うまくいけば、

receiveValue: {weather in
 print(weather.name)
 print(weather.link)
}

で出力され、最後に。

 case .finished:
   print("終了")

が実行され"終了"が出力されます。

失敗すれば

case .failure(let error):
   print(error.localizedDescription)

が実行されエラーとなります。

Combineを使うことでコードをスッキリ書くことができます。

この記事が気に入ったらサポートをしてみませんか?