{"id":199,"date":"2022-02-24T03:39:42","date_gmt":"2022-02-23T18:39:42","guid":{"rendered":"https:\/\/byeon.is\/?p=199"},"modified":"2022-11-19T18:55:02","modified_gmt":"2022-11-19T09:55:02","slug":"swift-concurrency-async-await-with-alamofire","status":"publish","type":"post","link":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/","title":{"rendered":"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30"},"content":{"rendered":"\n

Alamofire 5.5[#<\/a>] \ubc84\uc804\ubd80\ud130 Concurrency\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \uacf5\uc2dd \ubb38\uc11c<\/a>\uc758 \uc124\uba85\uc744 \ubcf4\uba74 \uc544\ub798\uc640 \uac19\uc774 \uc801\ud600\uc788\ub2e4.<\/p>\n\n\n\n

<\/p>Alamofire’s concurrency support requires Swift 5.5.2 or Xcode 13.2. These examples also include the use of static protocol values added in Alamofire 5.5 for Swift 5.5.<\/cite><\/blockquote>\n\n\n\n

\uc4f0\uae30 \uc704\ud574\uc11c\ub294 Xcode 13.2\ub85c \uc5c5\ub370\uc774\ud2b8\ubd80\ud130 \ud574\uc8fc\uc790!<\/p>\n\n\n\n

\ud504\ub85c\uc81d\ud2b8\uc758 \ucd5c\uc18c iOS \ubc84\uc804\uc744 13\uc73c\ub85c \ub9de\ucdb0\uc900\ub2e4.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

\uadf8\ub9ac\uace0 Alamofire\uc758 5.5 \ubc84\uc804\uc744 \ubc1b\uc544\uc8fc\uc790. \ud544\uc790\ub294 Swift Package Manager\ub97c \ud1b5\ud574 \ubc1b\uc74c. (\uc2a4\uc0f7\uc5d0 \uc788\ub294 5.5.01\ub294 \uc62c\ubc14\ub978 \ubc84\uc804\uc774 \uc544\ub2c8\ubbc0\ub85c 5.5.0\uc73c\ub85c \ubc1b\uc73c\uc138\uc694~!)<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

\uc774\uc81c \uc0ac\uc6a9\ud560 \uc900\ube44\ub294 \ub05d\ub0ac\ub2e4. \uc774\uc81c \uc0ac\uc6a9\ud560 Session\uc744 \uc544\ub798\uc640 \uac19\uc774 \uc815\uc758\ud574\uc8fc\uc790.<\/p>\n\n\n\n

  private let session: Session = {\n    let configuration = URLSessionConfiguration.default\n    configuration.timeoutIntervalForRequest = 10\n    configuration.timeoutIntervalForResource = 10\n    return Session(configuration: configuration)\n  }()<\/code><\/pre>\n\n\n\n

\uadf8 \ub2e4\uc74c\uc740 requestJSON \ud568\uc218\ub97c \uad6c\ud604\ud574\ubcf4\uc790. Alamofire\uc744 \uc0ac\uc6a9\ud558\uba74 \uc815\ub9d0 \uac04\ub2e8\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n

  func requestJSON<T: Decodable>(_ url: String,\n                                 type: T.Type,\n                                 method: HTTPMethod,\n                                 parameters: Parameters? = nil) async throws -> T {\n    \n    return try await session.request(url,\n                                     method: method,\n                                     parameters: parameters,\n                                     encoding: URLEncoding.default)\n      .serializingDecodable()\n      .value\n  }<\/code><\/pre>\n\n\n\n

DataRequest -> DataTask -> value \uc18d\uc131 \uc811\uadfc\uc73c\ub85c DataResponse\uc758 Success \uac12\uc744 \uac00\uc838\uc62c \uc218 \uc788\ub2e4.<\/p>\n\n\n\n

\ub124\ud2b8\uc6cc\ud06c \ud1b5\uc2e0 \uc804\uccb4 \ucf54\ub4dc<\/h4>\n\n\n\n
import Foundation\nimport Alamofire\n\nfinal class AppNetworking {\n  static let shared = AppNetworking()\n  \n  private init() { }\n  \n  private let session: Session = {\n    let configuration = URLSessionConfiguration.default\n    configuration.timeoutIntervalForRequest = 10\n    configuration.timeoutIntervalForResource = 10\n    return Session(configuration: configuration)\n  }()\n  \n  func requestJSON<T: Decodable>(_ url: String,\n                                 type: T.Type,\n                                 method: HTTPMethod,\n                                 parameters: Parameters? = nil) async throws -> T {\n    \n    return try await session.request(url,\n                                     method: method,\n                                     parameters: parameters,\n                                     encoding: URLEncoding.default)\n      .serializingDecodable()\n      .value\n  }\n}<\/code><\/pre>\n\n\n\n

\ub098\ub294 \uac04\ub2e8\ud558\uac8c api.icndb.com\/jokes\/random<\/code> \uc0ac\uc774\ud2b8\uc758 \uc751\ub2f5\uac12\uc744 UITableView<\/code>\uc5d0 \ubfcc\ub9ac\ub294 \ucf54\ub4dc\ub97c \uc791\uc131\ud574\ubcf4\uc558\ub2e4.<\/p>\n\n\n\n

\ubaa8\ub378\uc740 \uc544\ub798\uc640 \uac19\uc774 \uc815\uc758\ud588\ub2e4.<\/p>\n\n\n\n

\nstruct Joke: Codable {\n  let type: String\n  let value: [Value]\n  \n  struct Value: Codable {\n    let id: Int\n    let joke: String\n  }\n}\n\n<\/code><\/pre>\n\n\n\n

\uc774\uc81c ViewController \ucf54\ub4dc\ub97c \uc544\ub798\uc640 \uac19\uc774 \uc791\uc131\ud574\uc8fc\uba74 \ub41c\ub2e4.<\/p>\n\n\n\n

class ViewController: UIViewController {\n\n  @IBOutlet weak var tableView: UITableView!\n  \n   private var jokes: [Joke.Value] = []\n  \n  override func viewDidLoad() {\n    super.viewDidLoad()\n    tableView.dataSource = self\n    \n    Task {\n      await retrieveJokes()\n    }\n  }\n  \n  private func retrieveJokes() async {\n    do {\n      let joke = try await AppNetworking.shared.requestJSON(\"https:\/\/api.icndb.com\/jokes\/random\/50\",\n                                                             type: Joke.self,\n                                                             method: .get,\n                                                             parameters: nil)\n      updateUI(jokes: joke.value)\n    } catch {\n      updateUI(error: error)\n    }\n  }\n  \n  @MainActor\n  private func updateUI(error: Error) {\n    let label = UILabel()\n    label.numberOfLines = 0\n    label.text = error.localizedDescription\n    label.frame = view.bounds\n    view.addSubview(label)\n  }\n  \n  @MainActor\n  private func updateUI(jokes: [Joke.Value]) {\n    self.jokes = jokes\n    tableView.reloadData()\n  }\n}\n\n\/\/ MARK: - UITableViewDataSource\nextension ViewController: UITableViewDataSource {\n  func numberOfSections(in tableView: UITableView) -> Int {\n     return 1\n  }\n  \n  func tableView(_ tableView: UITableView,\n                 numberOfRowsInSection section: Int) -> Int {\n    return jokes.count\n  }\n  \n  func tableView(_ tableView: UITableView,\n                 cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n    let cell = UITableViewCell()\n    cell.textLabel?.text = jokes[indexPath.row].joke\n    cell.textLabel?.numberOfLines = 0\n    return cell\n  }\n}\n\n<\/code><\/pre>\n\n\n\n

\ucf54\ub4dc\ub97c \uac04\ub2e8\ud558\uac8c \uc0b4\ud3b4\ubcf4\uc790\uba74 requestJSON<\/code> \ud568\uc218\ub294 retrieveJokes \ud568\uc218\uc5d0\uc11c \ud638\ucd9c\ud558\ub3c4\ub85d \ud558\uc600\uace0 \b\ubdf0\uac00 \ub85c\ub4dc\ub41c\ub2e4\uba74 retrieveJokes \ud568\uc218\ub97c \ud638\ucd9c\ud558\ub3c4\ub85d \ud558\uc600\ub2e4. viewDidLoad<\/code> \uc758 \uacbd\uc6b0 func viewDidLoad() async \ud615\ud0dc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uae30 \ub54c\ubb38\uc5d0 Task<\/a>\ub97c \ud1b5\ud574 async \/ await\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc8fc\uc5c8\ub2e4.<\/p>\n\n\n\n

\uadf8\ub9ac\uace0 \uae30\ubcf8\uc801\uc73c\ub85c async \/ await\ub97c \ud1b5\ud574 \uc2e4\ud589\ub41c \ucf54\ub4dc\ub294 \uba54\uc778 \uc2a4\ub808\ub4dc\uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uac83\uc774 \uc544\ub2c8\ub77c\uc11c, UI \uc5c5\ub370\uc774\ud2b8 \uac19\uc740 \uc791\uc5c5\uc744 \uc218\ud589\ud560 \ub550 \b\uba54\uc778 \uc2a4\ub808\ub4dc\uc5d0\uc11c \uc2e4\ud589\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc8fc\uc5b4\uc57c \ud558\ub294\ub370(\ucf54\ub4dc\uc5d0\uc11c\ub294 reloadData<\/code>\ub97c \uc0ac\uc6a9\ud588\uc9c0\ub9cc, performBatchUpdates<\/code>\uc640 \uac19\uc740 \ud568\uc218\ub97c \ud638\ucd9c\ud560 \ub550 \uba54\uc778 \uc2a4\ub808\ub4dc\uc5d0\uc11c \uc811\uadfc\ud558\uc5ec\uc57c \ud55c\ub2e4), \ucf54\ub4dc\ub9c8\ub2e4 DispatchQueue.main.async<\/code>\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83 \ubcf4\ub2e8 MainActor<\/a> \ub77c\ub294 attribute\ub97c \ud1b5\ud574 \uc880 \ub354 \uae54\ub054\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\ub2e4. (+ \ub0b4\uc6a9\ucd94\uac00 : UIViewController\uac00 MainActor\ub85c \uc815\uc758\ub418\uc5b4 \uc788\uc5b4, \ubdf0 \ucee8\ud2b8\ub864\ub7ec \uc548\uc758 \uba54\uc18c\ub4dc\ub4e4\uc740 \uc790\ub3d9\uc801\uc73c\ub85c MainActor\uc5d0\uc11c \uc2e4\ud589\ub429\ub2c8\ub2e4 #<\/a>)<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

iOS 13 \uc5d0\uc11c\ub3c4 \uc2e4\ud589\ub418\ub294\uac78 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n

\uc18c\uc2a4 \ucf54\ub4dc: https:\/\/github.com\/chorim\/AlamofireConcurrencyDemo<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

Alamofire 5.5[#] \ubc84\uc804\ubd80\ud130 Concurrency\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \uacf5\uc2dd \ubb38\uc11c\uc758 \uc124\uba85\uc744 \ubcf4\uba74 \uc544\ub798\uc640 \uac19\uc774 \uc801\ud600\uc788\ub2e4. Alamofire’s concurrency support requires Swift 5.5.2 or Xcode 13.2. These examples also include the use of static protocol… Continue reading “[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30”<\/span> <\/span><\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"yoast_head":"\n[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30 - \ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30 - \ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4\" \/>\n<meta property=\"og:description\" content=\"Alamofire 5.5[#] \ubc84\uc804\ubd80\ud130 Concurrency\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \uacf5\uc2dd \ubb38\uc11c\uc758 \uc124\uba85\uc744 \ubcf4\uba74 \uc544\ub798\uc640 \uac19\uc774 \uc801\ud600\uc788\ub2e4. Alamofire’s concurrency support requires Swift 5.5.2 or Xcode 13.2. These examples also include the use of static protocol… Continue reading "[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30"\" \/>\n<meta property=\"og:url\" content=\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/\" \/>\n<meta property=\"og:site_name\" content=\"\ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4\" \/>\n<meta property=\"article:published_time\" content=\"2022-02-23T18:39:42+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-11-19T09:55:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/byeon.is\/wp-content\/uploads\/2022\/02\/image-6-1024x377.png\" \/>\n<meta name=\"author\" content=\"\ucd08\ub9bc\uc774\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"\ucd08\ub9bc\uc774\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/\"},\"author\":{\"name\":\"\ucd08\ub9bc\uc774\",\"@id\":\"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036\"},\"headline\":\"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30\",\"datePublished\":\"2022-02-23T18:39:42+00:00\",\"dateModified\":\"2022-11-19T09:55:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/\"},\"wordCount\":69,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036\"},\"articleSection\":[\"Swift\"],\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/\",\"url\":\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/\",\"name\":\"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30 - \ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4\",\"isPartOf\":{\"@id\":\"https:\/\/byeon.is\/#website\"},\"datePublished\":\"2022-02-23T18:39:42+00:00\",\"dateModified\":\"2022-11-19T09:55:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/byeon.is\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/byeon.is\/#website\",\"url\":\"https:\/\/byeon.is\/\",\"name\":\"\ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4\",\"description\":\"Swift \uac1c\ubc1c \uba54\ubaa8\uc7a5\",\"publisher\":{\"@id\":\"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/byeon.is\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"ko-KR\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036\",\"name\":\"\ucd08\ub9bc\uc774\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/byeon.is\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/byeon.is\/wp-content\/litespeed\/avatar\/cf051b81c9c51e8a825604429397999f.jpg?ver=1715547606\",\"contentUrl\":\"https:\/\/byeon.is\/wp-content\/litespeed\/avatar\/cf051b81c9c51e8a825604429397999f.jpg?ver=1715547606\",\"caption\":\"\ucd08\ub9bc\uc774\"},\"logo\":{\"@id\":\"https:\/\/byeon.is\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/blog.yuki.kr\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30 - \ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/","og_locale":"ko_KR","og_type":"article","og_title":"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30 - \ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4","og_description":"Alamofire 5.5[#] \ubc84\uc804\ubd80\ud130 Concurrency\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \uacf5\uc2dd \ubb38\uc11c\uc758 \uc124\uba85\uc744 \ubcf4\uba74 \uc544\ub798\uc640 \uac19\uc774 \uc801\ud600\uc788\ub2e4. Alamofire’s concurrency support requires Swift 5.5.2 or Xcode 13.2. These examples also include the use of static protocol… Continue reading \"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30\"","og_url":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/","og_site_name":"\ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4","article_published_time":"2022-02-23T18:39:42+00:00","article_modified_time":"2022-11-19T09:55:02+00:00","og_image":[{"url":"https:\/\/byeon.is\/wp-content\/uploads\/2022\/02\/image-6-1024x377.png"}],"author":"\ucd08\ub9bc\uc774","twitter_card":"summary_large_image","twitter_misc":{"Written by":"\ucd08\ub9bc\uc774","Est. reading time":"4\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#article","isPartOf":{"@id":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/"},"author":{"name":"\ucd08\ub9bc\uc774","@id":"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036"},"headline":"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30","datePublished":"2022-02-23T18:39:42+00:00","dateModified":"2022-11-19T09:55:02+00:00","mainEntityOfPage":{"@id":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/"},"wordCount":69,"commentCount":0,"publisher":{"@id":"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036"},"articleSection":["Swift"],"inLanguage":"ko-KR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/","url":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/","name":"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30 - \ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4","isPartOf":{"@id":"https:\/\/byeon.is\/#website"},"datePublished":"2022-02-23T18:39:42+00:00","dateModified":"2022-11-19T09:55:02+00:00","breadcrumb":{"@id":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/byeon.is\/swift-concurrency-async-await-with-alamofire\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/byeon.is\/"},{"@type":"ListItem","position":2,"name":"[Swift] Alamofire async \/ await \uc0ac\uc6a9\ud574\ubcf4\uae30"}]},{"@type":"WebSite","@id":"https:\/\/byeon.is\/#website","url":"https:\/\/byeon.is\/","name":"\ucd08\ub9bc\uc774\uc758 \uc5f0\uad6c\uc2e4","description":"Swift \uac1c\ubc1c \uba54\ubaa8\uc7a5","publisher":{"@id":"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/byeon.is\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"ko-KR"},{"@type":["Person","Organization"],"@id":"https:\/\/byeon.is\/#\/schema\/person\/fc39470e20971f6e096647e8817ca036","name":"\ucd08\ub9bc\uc774","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/byeon.is\/#\/schema\/person\/image\/","url":"https:\/\/byeon.is\/wp-content\/litespeed\/avatar\/cf051b81c9c51e8a825604429397999f.jpg?ver=1715547606","contentUrl":"https:\/\/byeon.is\/wp-content\/litespeed\/avatar\/cf051b81c9c51e8a825604429397999f.jpg?ver=1715547606","caption":"\ucd08\ub9bc\uc774"},"logo":{"@id":"https:\/\/byeon.is\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/blog.yuki.kr"]}]}},"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":347,"url":"https:\/\/byeon.is\/swift-tuist-dependency-objective-c-library-error\/","url_meta":{"origin":199,"position":0},"title":"[Swift] Tuist\uc5d0\uc11c SPM\uc73c\ub85c \ucd94\uac00\ud55c Objective-C\ub85c \ub9cc\ub4e0 \ub77c\uc774\ube0c\ub7ec\ub9ac \uc5d0\ub7ec \ud574\uacb0\ud558\ub294 \ubc95","author":"\ucd08\ub9bc\uc774","date":"2023\ub144 3\uc6d4 4\uc77c","format":false,"excerpt":"\uc774 \uae00\uc740 tuist 3.7.0 \ubc84\uc804 \uae30\uc900\uc73c\ub85c \uc791\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. (\uc81c\ubaa9 \ucc38 \uae38\ub2e4) Tuist\uc5d0\uc11c \uc77c\ubc18\uc801\uc73c\ub85c \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \ucd94\uac00\ud558\ub294 \ubc29\ubc95\uc740 \uc544\ub798\uc640 \uac19\ub2e4. Tuist\uc758 Swift Package Manager Tuist\uc758 Carthage Xcode\uc5d0\uc11c \uc0ac\uc6a9\ub418\ub294 Swift Package Manager XCFramework CocoaPods \ud3c9\uc18c\uc5d0 Tuist\uc758 \ub514\ud39c\ub358\uc2dc \uad00\ub9ac\ub97c 1\ubc88\uc73c\ub85c \ud558\uac8c \ub418\ub294\ub370 Objective-C\ub85c \ub9cc\ub4e4\uc5b4\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc744 \ucd94\uac00\ud560 \ub54c \ub9c8\ub2e4 \ube4c\ub4dc \uc624\ub958 \ub610\ub294 \ub7f0\ud0c0\uc784 \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4...\u2026","rel":"","context":""Swift"\uc5d0\uc11c","block_context":{"text":"Swift","link":"https:\/\/byeon.is\/category\/swift\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2023\/03\/image.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2023\/03\/image.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2023\/03\/image.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2023\/03\/image.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2023\/03\/image.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":155,"url":"https:\/\/byeon.is\/swift-xcode-13-uinavigation-and-uitabbar-appearance-bug\/","url_meta":{"origin":199,"position":1},"title":"[Swift] Xcode 13 UINavigationBar and UITabBar appearance bug","author":"\ucd08\ub9bc\uc774","date":"2021\ub144 10\uc6d4 2\uc77c","format":false,"excerpt":"Declare private methods \/\/ MARK: - Private Methods extension AppDelegate { func setupNavigationAppearance() { let appearance = UINavigationBarAppearance() let navigationBar = UINavigationBar() appearance.configureWithOpaqueBackground() appearance.backgroundColor = UIColor.white navigationBar.standardAppearance = appearance UINavigationBar.appearance().scrollEdgeAppearance = appearance } func setupTabBarAppearance() { let appearance = UITabBarAppearance() let tabBar = UITabBar() appearance.configureWithOpaqueBackground() appearance.backgroundColor = .white tabBar.standardAppearance =\u2026","rel":"","context":""Swift"\uc5d0\uc11c","block_context":{"text":"Swift","link":"https:\/\/byeon.is\/category\/swift\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":177,"url":"https:\/\/byeon.is\/swift-install-ribs-using-carthage\/","url_meta":{"origin":199,"position":2},"title":"[Swift] RIBs\ub97c Carthage\ub85c \uc124\uce58\ud574\ubcf4\uae30","author":"\ucd08\ub9bc\uc774","date":"2022\ub144 2\uc6d4 1\uc77c","format":false,"excerpt":"\uae30\uc874\uc5d0 CocoaPods\ub85c\ub9cc \ud328\ud0a4\uc9c0\ub4e4\uc744 \uad00\ub9ac\ud588\uc5c8\ub294\ub370, \uc2ec\uc2ec\ud574\uc11c Carthage\ub85c\ub3c4 \uad6c\uc131\ud574\ubd24\ub358 \uacbd\ud5d8\uc744 \uae30\ub85d\ud574\ubcf8\ub2e4. Carthage\ub97c Homebrew\ub97c \ud1b5\ud574 \uc124\uce58\ud55c\ub2e4. $ brew install carthage 2. \ud504\ub85c\uc81d\ud2b8\ub0b4\uc5d0 Cartfile\uc744 \uc0dd\uc131\ud55c\ub2e4. $ touch Cartfile $ open -a Xcode Cartfile 3. Cartfile\uc5d0 \uc544\ub798\uc640 \uac19\uc774 \uc791\uc131\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4. github \"uber\/RIBs\" \"master\" github \"ReactiveX\/RxSwift\" 4. Xcode 12 \uc774\uc0c1\ubd80\ud130 Carthage\uc758 \ube4c\ub4dc \uc774\uc288[#]\uac00 \uc788\uc73c\ubbc0\ub85c \uacf5\uc2dd \ubb38\uc11c\ub97c\u2026","rel":"","context":""Swift"\uc5d0\uc11c","block_context":{"text":"Swift","link":"https:\/\/byeon.is\/category\/swift\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2022\/02\/image.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2022\/02\/image.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2022\/02\/image.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2022\/02\/image.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":166,"url":"https:\/\/byeon.is\/swift-%eb%84%a4%ec%9d%b4%eb%b2%84-%ec%98%81%ed%99%94-%ea%b2%80%ec%83%89-%ec%95%b1-ribs-tuist%eb%a1%9c-%eb%a7%8c%eb%93%a4%ec%96%b4%eb%b3%b4%ea%b8%b0-1\/","url_meta":{"origin":199,"position":3},"title":"[Swift] \ub124\uc774\ubc84 \uc601\ud654 \uac80\uc0c9 \uc571 RIBs + Tuist\ub85c \ub9cc\ub4e4\uc5b4\ubcf4\uae30 – 1","author":"\ucd08\ub9bc\uc774","date":"2021\ub144 12\uc6d4 4\uc77c","format":false,"excerpt":"\ud68c\uc0ac\uc5d0\uc11c \uac10\uc0ac\ud558\uac8c\ub3c4 RIBs + Tuist\ub85c \uac1c\ubc1c\ud560 \uc218 \uc788\ub294 \uae30\ud68c\uac00 \uc8fc\uc5b4\uc84c\ub294\ub370(\uc548\ud574\uc904 \uac83 \uac19\uc558\ub294\ub370..), \uc544\ubb34\ub798\ub3c4 \ucc98\uc74c \uc2dc\ub3c4 \ud574\ubcf4\ub294 \uac83\ub4e4\uc774\ub2e4\ubcf4\ub2c8 \uae30\ucd08 \uc9c0\uc2dd\uc774 \ubd80\uc871\ud574\uc11c \uc0d8\ud50c \uc571\uc744 \uba87\uac1c \ub354 \ub9cc\ub4e4\uc5b4\ubd10\uc57c\ud560 \uac83 \uac19\uc544 \uae30\ub85d\uc6a9\uc73c\ub85c \ub0a8\uae34\ub2e4. \uc77c\ub2e8 \uac00\uc7a5 \uba3c\uc800 tuist\ub85c \ud504\ub85c\uc81d\ud2b8\ub97c \uad6c\uc131\ud55c\ub2e4. \u276f tuist init --platform ios \uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub97c \uac16\uac8c \ub41c\ub2e4. \u276f tree . . \u251c\u2500\u2500\u2026","rel":"","context":""Swift"\uc5d0\uc11c","block_context":{"text":"Swift","link":"https:\/\/byeon.is\/category\/swift\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":72,"url":"https:\/\/byeon.is\/swift-flatmap-compactmap\/","url_meta":{"origin":199,"position":4},"title":"[Swift] flatMap? compactMap?","author":"\ucd08\ub9bc\uc774","date":"2020\ub144 9\uc6d4 21\uc77c","format":false,"excerpt":"4~5\ub144 \uc804\ubd80\ud130 \uac1c\ubc1c\ud558\uace0 \uc788\ub294 \uc571\uc774 \uc810\uc810 \ub808\uac70\uc2dc \ucf54\ub4dc\uac00 \ub108\ubb34 \ub9ce\uc544\uc838\uc11c Warning\uc774 300~400\uac1c\uac00 \ub118\uc5b4\uac00\uace0 \uc788\ub2e4. \uac1c\ubc1c\ud558\uba74\uc11c \uc5ec\uc720\uac00 \uc5c6\uc5b4\uc11c \ub808\uac70\uc2dc \ucf54\ub4dc\ub97c \uac1c\uc120\ud560 \uc0dd\uac01\uc774 \uc5c6\uc5c8\ub294\ub370 \uc774\ubc88\uc5d0 \uc2dc\uac04\uc774 \uc880 \uc5ec\uc720\uac00 \uc0dd\uae30\uba74\uc11c \ub9c8\uc74c\uba39\uace0 \uac1c\uc120\uc744 \ud558\ub294 \ub3c4\uc911 flatMap\uc640 compactMap \uad00\ub828\uc73c\ub85c \uc6cc\ub2dd\uc774 \ub728\uace0 \uc788\uae38\ub798 \uac04\ub2e8\ud558\uac8c \uae00\uc744 \uc368\ubcfc\ub824\uace0 \ud55c\ub2e4. ???? flatMap\uc774\ub791 compactMap\uc774 \ubb50\uc5d0\uc694? flatMap\uc740 \ub2e4\ub978 \uc5b8\uc5b4\uc5d0\uc11c \uc790\uc8fc \ub4e4\uc5b4\ubcf4\uc558\ub294\ub370\u2026","rel":"","context":""Swift"\uc5d0\uc11c","block_context":{"text":"Swift","link":"https:\/\/byeon.is\/category\/swift\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2020\/09\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2020-09-21-\u110b\u1169\u1112\u116e-3.09.20-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2020\/09\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2020-09-21-\u110b\u1169\u1112\u116e-3.09.20-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2020\/09\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2020-09-21-\u110b\u1169\u1112\u116e-3.09.20-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2020\/09\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2020-09-21-\u110b\u1169\u1112\u116e-3.09.20-1.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/byeon.is\/wp-content\/uploads\/2020\/09\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2020-09-21-\u110b\u1169\u1112\u116e-3.09.20-1.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":68,"url":"https:\/\/byeon.is\/swift-clean-code-using-enum\/","url_meta":{"origin":199,"position":5},"title":"Swift enum \ud65c\uc6a9\ud558\uae30","author":"\ucd08\ub9bc\uc774","date":"2020\ub144 9\uc6d4 15\uc77c","format":false,"excerpt":"Swift\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 Enum\uc774 \uc815\ub9d0 \ud65c\uc6a9\ub3c4\uac00 \ub192\ub2e4\ub294 \uac78 \uc54c \uc218 \uc788\ub2e4. \ub098 \uac19\uc740 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\uc790\uc758 \uae30\uae30 \uc815\ubcf4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\uc5b4\uc57c\ud558\ub294 \uac1d\uccb4\uac00 \ud544\uc694\ud588\ub2e4. \uadf8\ub9ac\uace0 \uc11c\ubc84\uc5d0 \uc804\uc1a1\ud560 \uc218 \uc788\uc5b4\uc57c \ud588\ub2e4. \uadf8\ub798\uc11c enum\uc744 \ud65c\uc6a9\ud558\uc5ec \ub098\ub294 \uae30\uae30 \uc815\ubcf4\ub4e4\uc744 \uc800\uc7a5\ud560 \ubcc0\uc218\ub97c \ub9cc\ub4e4\uae30\ub85c \ud588\ub2e4. class DeviceService { static let shared = DeviceService() } \uc704\uc640 \uac19\uc740 \ud074\ub798\uc2a4\uac00 \uc788\ub2e4\uace0 \uc0dd\uac01\ud574\ubcf4\uc790.\u2026","rel":"","context":""Swift"\uc5d0\uc11c","block_context":{"text":"Swift","link":"https:\/\/byeon.is\/category\/swift\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/posts\/199"}],"collection":[{"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/comments?post=199"}],"version-history":[{"count":16,"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/posts\/199\/revisions"}],"predecessor-version":[{"id":295,"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/posts\/199\/revisions\/295"}],"wp:attachment":[{"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/media?parent=199"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/categories?post=199"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/byeon.is\/wp-json\/wp\/v2\/tags?post=199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}