見出し画像

SwiftUIでいこう! - Search App! - 1

Jsonでデータを取得して、リストに表示します。検索ができるようのもします。以下参考サイト。

2つにViewを作っていきます。まず一つ目はSwitUIのみで組み上げます。

struct EmptyStateView:View{
   var body: some View{
       VStack{
           Spacer()
           Image(systemName: "music.note")
               .font(.system(size:85))
               .padding(.bottom)
           Text("Start searching for music ... ")
               .font(.title)
           Spacer()
       }
       .padding()
       .foregroundColor(Color(.systemIndigo))
   }
}

もう一つはUIKitを使うので、SwiftUIで使えるようにプロトコルUIViewRepresentableに適応させます。

struct SearchBar:UIViewRepresentable {
   typealias UIViewType = UISearchBar
   
   func makeUIView(context: Context) -> UISearchBar {
       let searchBar = UISearchBar(frame:.zero)
       searchBar.delegate = context.coordinator
       searchBar.searchBarStyle = .minimal
       searchBar.placeholder = "Type a song"
       return searchBar
   }
   
   func updateUIView(_ uiView: UISearchBar, context: Context) {
   }
   
   func makeCoordinator() -> SearchBarCordinator {
       SearchBarCordinator()
   }
   
   class SearchBarCordinator:NSObject,UISearchBarDelegate{
   }
}

この2つをContentViewに入れ込みます。

 NavigationView{
           VStack{
               SearchBar()
               EmptyStateView()
           }
           .navigationBarTitle("Music Search")

表示画面ができてきたので、データ部分を作っていきます。

画像1

中身です。Jsonを読み込んでデータを表示させために配列に変更していきます。

まずDecodableに対応させ、取得するJsonに合わせていきます。

struct SongResPonse:Decodable{
   let songs : [Song]
   
   enum CodingKeys:String,CodingKey{
       case songs = "results"
   }
}

struct Song:Decodable {
   let id:Int
   let trackName:String
   let artistName:String
   let artworkUrl:String
   
   enum CodingKeys: String,CodingKey{
       case id = "trackId"
       case trackName
       case artistName
       case artworkUrl = "artworkUrl60"
   }
}

そして解析して使うことのできる配列にしていきます。

class DataModel{}

を作っていきます。

https://itunes.apple.com/search?term=coldplay&entity=song

のサイトからJsonファイルを取得して解析してデータとして使えるようにしていきます。まず準備ですが、Codableに準拠させていきます。サイトにあるJsonファイルにある項目に対して変数を作っていきます。

struct SongResPonse:Decodable{
   let songs : [Song]
   
   enum CodingKeys:String,CodingKey{
       case songs = "results"
   }
}

struct Song:Decodable {
   let id:Int
   let trackName:String
   let artistName:String
   let artworkUrl:String
   
   enum CodingKeys: String,CodingKey{
       case id = "trackId"
       case trackName
       case artistName
       case artworkUrl = "artworkUrl60"
   }
}

そしてクラスを作っていきます。

必要なURLからそのデータを取り出す関数を作ります。

  private func buildUrl(forTerm searchTerm:String) -> URL?{
       guard  !searchTerm.isEmpty else {
           return nil
       }
       
       let quaryItem = [
       URLQueryItem(name: "term", value: searchTerm),
       URLQueryItem(name: "entity", value: "song")
       ]
       var components = URLComponents(string: "https://itunes.apple.com/search")
       components?.queryItems = quaryItem
       return components?.url
   }

そしてJsonをパースするコードを書いていきます。

 private var dataTask:URLSessionDataTask?
   
   func loadSongs(searchTerm:String,completion:@escaping(([Song])->Void)){
       dataTask?.cancel()
       guard let url = buildUrl(forTerm: searchTerm)  else {
           completion([])
           return
       }
       dataTask = URLSession.shared.dataTask(with: url){ data , _,  _ in
           guard let data  = data else{
               completion([])
               return
           }
           if let songResponse = try? JSONDecoder().decode(SongResPonse.self,from:data){
               completion(songResponse.songs)
           }
       }
       dataTask?.resume()
   }

URLSessionから、try? JSONDecoder()でJsonファイルをリスト表示で使う配列へと変換します。

URLSessionを使う時に注意すること、使い方がまとめてあるので参考に。

次ではデータをリストにして表示できるようにしていきます。

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