Beginning Networking with URLSession

Sep 13 2022 · Swift 5.6, iOS 15, Xcode 13.4.1

Part 1: Introduction to URLSession & Concurrency

03. More Modern Concurrency

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 02. Introduction to Modern Concurrency Next episode: 04. Challenge: Run Code on the Main Thread

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 03. More Modern Concurrency

Concurrency - The Swift Programming Language

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

Continuing from the previous episode, let’s take a look at more of Swift’s modern concurrency features.

func findTitle(url: URL) async throws -> String? {
  for try await line in url.lines {
    if line.contains("<title>") {
      return line.trimmingCharacters(in: .whitespaces)
    }
  }
    
  return nil
}
Task {
  if let title = try await findTitle(url: URL(string: "https://www.raywenderlich.com")!) {
    print(title)
  }
}
extension Domains {
  static var domains: [Domain] {
    get async throws {
      try await fetchDomains()
    }
  }
}
Task {
  dump(try await Domains.domains)
}
extension Domains {
  enum Error: Swift.Error { case outOfRange }
    
  static subscript(_ index: Int) -> String {
    get async throws {
      let domains = try await Self.domains
      guard domains.indices.contains(index) else {
        throw Error.outOfRange
      }
      return domains[index].attributes.name
    }
  }
}

Task {
  dump(try await Domains[4])
}
public actor Playlist {
public func move(song: String, from playlist: Playlist) async
public func move(song: String, to playlist: Playlist) async 
public func move(song: String, from playlist: Playlist) async {
  await playlist.remove(song: song)
  add(song: song)
}
public func move(song: String, to playlist: Playlist) async {
   await playlist.add(song: song)
   remove(song: song)
}
let favoritesPlaylist = Playlist(title: "Favorite songs",
                                author: "Felipe",
                                songs: ["In And Out Of Love"])
let partyPlaylist = Playlist(title: "Party songs",
                            author: "Ray",
                            songs: ["Hello"])
Task {
 await favoritesPlaylist.move(song: "Hello", from: partyPlaylist)
 await favoritesPlaylist.move(song: "In And Out Of Love", to: partyPlaylist)
 await print(favoritesPlaylist.songs)
 await print(partyPlaylist.songs)
}
let url = URL(string: "https://api.raywenderlich.com/api/domains")!
let session = URLSession.shared.dataTask(with: url) { data, _, _ in
  guard let data = data,
        let domain = try? JSONDecoder().decode(Domains.self, from: data).data.first
  else {
    print("Request failed")
        
    return
  }
    
  Task {
    await MainActor.run {
      print(domain)
      print(Thread.isMainThread)
    }
  }
}

session.resume()
Task { @MainActor in
  print(domain)
  print(Thread.isMainThread)
}
extension Domains {
  func domainNames() -> [String] {
    print("Getting domain names in main thread? \(Thread.isMainThread)")
        
    return data.map { $0.attributes.name }
  }
}

let session2 = URLSession.shared.dataTask(with: url) { data, _, _ in
  guard let data = data,
        let domains = try? JSONDecoder().decode(Domains.self, from: data)
  else {
    print("Request failed")
        
    return
  }

  print(domains.domainNames())
}

session2.resume()
@MainActor func domainNames() -> [String] {
Task {
  await print(domains.domainNames())
}