Skip to content

calledBlu/ios-weather-forecast

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

56 Commits
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

ios-weather-forecast

1. Team Introduce

2. Ground Rules

3. STEP๋ณ„ ๊ตฌํ˜„๋‚ด์šฉ

4. ํ•™์Šต๋‚ด์šฉ ๋ฐ ๋ฌธ์ œ ํ•ด๊ฒฐ


๐ŸŒ™ Team LuNna ๐ŸŒ™

๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿปโ€โ™‚๏ธ๐Ÿ’จ ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: 23.03.13 ~ 23.04.14

Blu Jenna

โ›ณ Ground Rules

  • ์ปค๋ฐ‹ ๊ทœ์น™
    • โœจย Git Commit Convention
      • Prefix ์ „์ฒด ์†Œ๋ฌธ์ž, [prefix]
      • featย = ์ฃผ๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ
      • fixย = ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์—์„œ bug๊ฐ€ ์ˆ˜์ •๋˜๋Š” ๊ฒฝ์šฐ
      • docsย = ๋ฌธ์„œ์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ๋Š” ๊ฒฝ์šฐ
      • config = ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ ์„ค์ • ์‹œ
      • styleย = ์„ธ๋ฏธ์ฝœ๋ก ์„ ๊นŒ๋จน์–ด์„œ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ ๊ฐ™์ด ํ˜•์‹์ ์ธ ๋ถ€๋ถ„์„ ๋‹ค๋ฃจ๋Š” ๊ฒฝ์šฐ (์ฝ”๋“œ์˜ ๋ณ€ํ™”๊ฐ€ ์ƒ์‚ฐ์ ์ธ ๊ฒƒ์ด ์•„๋‹Œ ๊ฒฝ์šฐ)
      • refactorย = production code๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ (๋ณ€์ˆ˜์˜ ๋„ค์ด๋ฐ์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ)
      • testย = ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜, ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ (์ฝ”๋“œ์˜ ๋ณ€ํ™”๊ฐ€ ์ƒ์‚ฐ์ ์ธ ๊ฒƒ์ด ์•„๋‹Œ ๊ฒฝ์šฐ)
      • choreย = ๋ณ„๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์ผ์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ (์ฝ”๋“œ์˜ ๋ณ€ํ™”๊ฐ€ ์ƒ์‚ฐ์ ์ธ ๊ฒƒ์ด ์•„๋‹Œ ๊ฒฝ์šฐ)
      • +) design = UI ๋””์ž์ธ์„ ๋ณ€๊ฒฝํ–ˆ์„ ๋•Œ
  • ๋ธŒ๋žœ์น˜ โ†’ step ๋ณ„๋กœ ๊ตฌ๋ถ„, PR ์‹œ main์œผ๋กœ ์ „์†ก
  • ์ฒœ์ฒœํžˆ ์ฐจ๊ทผ์ฐจ๊ทผ, ํ•˜๋‚˜์”ฉ ํ•˜๊ธฐ

๐Ÿ”จ STEP๋ณ„ ๊ตฌํ˜„ ๋‚ด์šฉ

STEP 1

  • ๋ชจ๋ธ/๋„คํŠธ์›Œํ‚น ํƒ€์ž… ๊ตฌํ˜„
    • Open Weather Map์˜ ๋‚ ์”จ API์˜ ๋ฐ์ดํ„ฐ ํ˜•์‹์„ ๊ณ ๋ คํ•œ ๋ชจ๋ธ ํƒ€์ž… ๊ตฌํ˜„
    • ์œ„๋„, ๊ฒฝ๋„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ ์”จ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋„๋ก WeatherURL ํƒ€์ž… ๊ตฌํ˜„
  • ๐Ÿ—๏ธ keyword: API Key, URLSession, Codable, JSONDecoder, CodingKey
  • STEP 1 PR ๐Ÿ”—

STEP 2

  • ์œ„์น˜์ •๋ณด ํ™•์ธ ๋ฐ ๋‚ ์”จ API ํ˜ธ์ถœ
    • ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์˜ ์œ„๋„์™€ ๊ฒฝ๋„๋ฅผ Custom์œผ๋กœ ์„ค์ •
    • CoreLocation๊ณผ API๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ์ขŒํ‘œ์˜ ๋‚ ์”จ Data ํ˜ธ์ถœ
    • CLLocationManagerDelegate์˜ locationManager(_:didUpdateLocations:)์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ locations๋กœ ํ˜„์žฌ ์œ„๋„, ๊ฒฝ๋„๋ฅผ ํฌํ•จํ•œ CLLocation ํƒ€์ž… ๊ฐ€์ ธ์˜ค๊ธฐ
  • ๐Ÿ—๏ธ keyword: CoreLocation, URLComponent, HTTP Method, CLGeocoder
  • STEP 2-1 PR ๐Ÿ”—
  • STEP 2-2 PR ๐Ÿ”—

STEP 3

  • UI๊ตฌํ˜„
    • Collection View๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์•ฑ์˜ UI ๊ตฌํ˜„
      • header view์— ํ˜„์žฌ ๋‚ ์”จ ์ ์šฉ
      • cell์— 5์ผ ์˜ˆ๋ณด ์ ์šฉ
    • ์ฝ”๋“œ๋ฒ ์ด์Šค AutoLayout ๊ตฌํ˜„
  • ๐Ÿ—๏ธ keyword: CollectionView, DateFormatter, UICollectionViewCompositionalLayout, URLComponents, UIRefreshControl
  • STEP 3-1 PR ๐Ÿ”—
  • STEP 3-2 PR ๐Ÿ”—

๐Ÿ“š ํ•™์Šต๋‚ด์šฉ ๋ฐ ๋ฌธ์ œ ํ•ด๊ฒฐ

1. API Key

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๋ฌธ์„œ: API Key, Keeping API Keys Safe

  • ํ•™์Šต ๋‚ด์šฉ
    • ๊ฐœ์ธ๋ณ„๋กœ ๋ฐœ๊ธ‰, API๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ key
    • ๊ณต๊ฐœํ•˜๋ฉด ์•ˆ ๋จ
  • ์ ์šฉ ๊ณผ์ •
    • url์ฟผ๋ฆฌ์— ๋“ค์–ด๊ฐ€๋Š” ๋‚ด์šฉ์ด๋ผ... โ†’ ํ˜„์žฌ๋Š” ๋ฌธ์ž์—ด ๋ฐฐ์—ด์„ .joined(separator: "&")์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์œผ๋‚˜, ๋‹ค์Œ ์Šคํ…์—์„œ URLQueryItem(์ถ”๊ฐ€ํ•™์Šตํ‚ค์›Œ๋“œ+)์— ๋Œ€ํ•œ ํ•™์Šต ์ง„ํ–‰ ํ›„ ๋ฆฌํŽ™ํ† ๋ง ์˜ˆ์ •!
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ
    • ์ˆจ๊ฒจ์•ผ ํ–ˆ์Œ โ†’ ์žฌ๋ฐœ๊ธ‰, ์ˆจ๊ธฐ๊ธฐ (์•„๋ž˜ ์งˆ๋ฌธ์‚ฌํ•ญ์—!)

2. URLSession

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ: URLSession

  • ํ•™์Šต ๋‚ด์šฉ
    • URLSession์€ ์‹ฑ๊ธ€ํ„ด ์ธ์Šคํ„ด์Šค(shared)๋ฅผ ์ œ๊ณต
    • ์ธ์Šคํ„ด์Šค๋ฉ”์„œ๋“œ '.data(for:URLRequest)'์˜ ๋ฐ˜ํ™˜ํ˜•์€ (Data, URLResponse)
  • ์ ์šฉ ๊ณผ์ •
    • api๋ณ„ url๋กœ URLRequest๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ์ธ์ˆ˜๋กœ ์‚ฌ์šฉ ('.data(from: URL)' ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ)
    • ์ง€๊ธˆ ๋‹จ๊ณ„์—์„  response ์—†์ด data๋งŒ ํ• ๋‹นํ•˜์—ฌ ํ™œ์šฉ โ†’ ๋‹ค์Œ ์Šคํ…์—์„œ ์‚ฌ์šฉํ•  ์˜ˆ์ •
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ
    • ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋Š” ๋น„๋™๊ธฐ๋กœ ์ด๋ฃจ์–ด์ง€๋˜, ๋ถˆ๋Ÿฌ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฑด ๋ฉ”์ธ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•จ
      • ๋™์ž‘ ํ™•์ธ ๋ฐฉ๋ฒ•: ViewController์˜ viewDidLoad()์—์„œ Task { ... } ์•ˆ์— ๋ฌถ์–ด์„œ ์‹คํ–‰
      • async-await ํ™œ์šฉ์— ๋„์ „ (๊ธฐํšŒ๊ฐ€ ๋œ๋‹ค๋ฉด GCD ๋“ฑ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ๋„ ํ•ด๋ณด๊ณ  ์‹ถ์–ด์š”!)

3. Codable, JSONDecoder

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ํ•™์Šต ๋‚ด์šฉ

    • Encodable๊ณผย Decodable์˜ ํ•ฉ์„ฑ ํ”„๋กœํ† ์ฝœ

    • JSONDecoder๋Š” Codable์„ ์ฑ„ํƒํ•œ class๋กœ, ์•„๋ž˜์˜ ์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด (JSONํ˜•์‹์˜)Data๋ฅผ ์›ํ•˜๋Š” ๋ชจ๋ธํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ

      func decode<T>(_ type: T.Type, from: Data) -> T {   }
  • ์ ์šฉ ๊ณผ์ •

    • ์•„๋ž˜ ์ด์œ ๋กœ, ๋ชจ๋ธ๋“ค์ด Codable์ด ์•„๋‹Œ Decodable๋งŒ ์ฑ„ํƒํ•˜๋„๋ก ํ•จ
      • decode(_:from:) ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด type๋งค๊ฐœ๋ณ€์ˆ˜์— ๋“ค์–ด๊ฐˆ ์ œ๋„ค๋ฆญ ์ธ์ž๋Š” Codable์ด ์•„๋‹Œ โ€˜Decodableโ€™๋งŒ ์ค€์ˆ˜ํ•˜๋ฉด ๋œ๋‹ค๋Š” ์กฐ๊ฑด์ž„
      • ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” API๋Š” ๋‚ ์”จ ๋ฐ์ดํ„ฐ๋กœ, encodingํ•˜๋Š” ์ƒํ™ฉ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์•„๋„ ๋จ
        (์• ์ดˆ์— ๋Œ€๋ถ€๋ถ„์˜ api๋Š” get ์ „์šฉ์œผ๋กœ ํ•œ์ •๋˜์–ด ์žˆ์Œ)
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ

    • .decode(type: ๋ชจ๋ธํƒ€์ž…๋ช…, from: api๋ฐ์ดํ„ฐ)์˜ โ€˜๋ชจ๋ธ ํƒ€์ž…๋ช…โ€™
      1. ํƒ€์ž… ๋ช…์„ ๋‹ฌ๋ฆฌ ํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”์„œ๋“œ๋‚˜ ํƒ€์ž…์„ ๋‘˜(ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•˜๋ฉด ๋‘˜ ์ด์ƒ) ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ weatherRange๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ–ˆ์Œ
      2. Decodable์„ ์ฑ„ํƒํ•˜๋ฉฐ weatherRangeํƒ€์ž…์†์„ฑ์„ ์š”๊ตฌํ•˜๋Š” whetherComposable ํ”„๋กœํ† ์ฝœ์„ ์ƒˆ๋กœ ์ •์˜ํ•˜์—ฌ, JSON๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ฌ ์ฃผ์š” ๋ชจ๋ธ 2๊ฐœ๊ฐ€ ์ค€์ˆ˜ํ•˜๋„๋ก ํ•จ
      3. WeatherParserํƒ€์ž…์— ์ œ๋„ค๋ฆญ(<T: WheterComposable>)์„ ์ ์šฉํ•˜์—ฌ T.self๋กœ โ€˜ํƒ€์ž…๋ช…โ€™์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•จ

4. CodingKey

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ: CodingKey

  • ํ•™์Šต ๋‚ด์šฉ
    • JSON data์˜ key์™€ ๋ชจ๋ธ์˜ ํ”„๋กœํผํ‹ฐ ๋„ค์ด๋ฐ์„ ๋‹ค๋ฅด๊ฒŒ ์“ฐ๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ, ์ธ์ฝ”๋”ฉ&๋””์ฝ”๋”ฉ ๊ณผ์ •์—์„œ ๋‘˜์„ ๋งค์นญํ•ด์ฃผ๋Š” โ€˜ํ”„๋กœํ† ์ฝœโ€™
    • ๋ณดํ†ต ํ•ด๋‹น ๋ชจ๋ธ ๋‚ด๋ถ€์— ์ค‘์ฒฉ์—ด๊ฑฐํ˜•์œผ๋กœ ์„ ์–ธํ•ด์„œ ์“ฐ๋ฉฐ, ๋ชจ๋ธ ๋‚ด ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•œ case๋ฅผ ์ž‘์„ฑํ•ด์ค˜์•ผ ํ•จ
  • ์ ์šฉ ๊ณผ์ •
    • ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ๊ธฐ์—๋Š” ๋„ค์ด๋ฐ ๊ฐ€์ด๋“œ๋ผ์ธ์— ์œ„๋ฐฐ๋˜๋Š” ๋ถ€๋ถ„์ด ๋งŽ์•˜์Œ โ†’ ๊ณ ์ณ์ค˜์•ผ ํ•ด์„œ ์“ธ ์ˆ˜๋ฐ–์— ์—†์—ˆ์Œ
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ
    • ๋ชจ๋ธ์˜ ํ”„๋กœํผํ‹ฐ ์ค‘ JSON Data์˜ key์™€ ์ผ์น˜ํ•˜๋Š” ํ•ญ๋ชฉ์ด ์—†๋Š” ๊ฒฝ์šฐ decoding ๊ณผ์ •์—์„œ error๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Œ
    • ViewController์˜ ViewDidLoad() ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์ง€ ์•Š๊ณ  LLDB๋ฅผ ํ†ตํ•ด ๋””๋ฒ„๊น…์„ ์‹œ๋„ํ•˜์˜€๊ณ  ๊ทธ ๊ณผ์ •์—์„œ p data๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ ๋ฐœ์ƒ
      error: expression failed to parse:
      warning: <EXPR>:11:7: warning: initialization of variable '$__lldb_error_result' was never used; consider replacing with assignment to '_' or removing it
        var $__lldb_error_result = __lldb_tmp_error
        ~~~~^~~~~~~~~~~~~~~~~~~~
        _
      
      error: <EXPR>:19:5: error: cannot find '$__lldb_injected_self' in scope
          $__lldb_injected_self.$__lldb_wrapped_expr_15(
          ^~~~~~~~~~~~~~~~~~~~~
    • ๊ณ ๋ฏผ ๋ฐ ๊ฒ€์ƒ‰ํ•ด ๋ณธ ๊ฒฐ๊ณผ lldb ๋””๋ฒ„๊ฑฐ๊ฐ€ ์ œ๋„ค๋ฆญ์„ ํ™œ์šฉํ•˜๋Š” ๋ถ€๋ถ„์ธ T.self๋ฅผ ์ถ”๋ก ํ•˜์ง€ ๋ชปํ•ด์„œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๋ผ๊ณ  ํŒ๋‹จ!
    • LLDB๋ฅผ ํ†ตํ•ด ๋””๋ฒ„๊น…ํ•˜๋Š” ๊ณผ์ •์„ ์ถ”๊ฐ€ ํ•™์Šตํ•˜๋„๋ก ํ•˜๊ณ , ์šฐ์„ ์ ์œผ๋กœ ์ •์ƒ ์ž‘๋™๋˜์—ˆ์„ ๋•Œ์˜ components๋“ค๊ณผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ์‹œ์ ์˜ components๋“ค๊ณผ ๋น„๊ตํ•˜์—ฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ถ€๋ถ„์„ ์ฐพ์•„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์—ˆ์Œ

5. CoreLocation

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ํ•™์Šต ๋‚ด์šฉ

    • Core Location์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” CoreLocation ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ importํ•ด์•ผ ํ•จ
    • Core Location์€ ์žฅ์น˜์˜ ์ง€๋ฆฌ์  ์œ„์น˜์™€ ๋ฐฉํ–ฅ์„ ์–ป๋Š” ๊ฒƒ์œผ๋กœ CLLocationManager ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋กœ Core Location ์„œ๋น„์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ณ  ์ค‘์ง€์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ
    • Core Location์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋Š” ์ •๋ณด
      • ์œ„์น˜ ์—…๋ฐ์ดํŠธ
      • ์ง€์—ญ ๋ชจ๋‹ˆํ„ฐ๋ง
      • iBeacon ๊ฐ์ง€ ๋ฐ ์ฐพ๊ธฐ
      • ๋‚˜์นจ๋ฐ˜์˜ ๋ฐฉํ–ฅ
    • Core Location์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์Šน์ธ์„ ์š”์ฒญํ•ด์•ผ ํ•จ
      • ์Šน์ธ ๋ณ€๊ฒฝ์„ ๋น„๋กฏํ•œ ์ด๋ฒคํŠธ๋Š” CLLocationManagerDelegate ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ฐœ์ฒด์—์„œ ์ˆ˜์‹ 
    • CLLocationManager ์ธ์Šคํ„ด์Šค๊ฐ€ ํ• ๋‹น๋˜๋ฉด ์‹œ์Šคํ…œ์ด delegate์˜ locationManagerDidChangeAuthorization(_:)๋ฉ”์„œ๋“œ์— ์•ฑ์˜ ์Šน์ธ ์ƒํƒœ๋ฅผ ๋ณด๊ณ ํ•จ
      • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— manager๊ฐ€ ๊ตฌ์„ฑ๋˜๋Š” ์‹œ์ ์— delegate๋ฅผ ์ฆ‰์‹œ ํ• ๋‹นํ•ด์•ผ ํ•จ
    • ์œ„์น˜ ์„œ๋น„์Šค ๊ถŒํ•œ
      • When In Use์™€ Always๊ฐ€ ์žˆ์Œ
      • ๊ณต์‹๋ฌธ์„œ์—์„œ๋Š” ๊ฐ€๋Šฅํ•˜๋ฉด When In Use๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ
      • ์œ„์น˜ ์ •๋ณด๋Š” ๋ฏผ๊ฐํ•œ ๊ฐœ์ธ์ •๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž์—๊ฒŒ ์œ„์น˜ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์„ค๋ช…์ด ํ•„์š”ํ•จ
  • ์ ์šฉ ๊ณผ์ •

    • ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์— ์ปค์Šคํ…€์œผ๋กœ ์„ค์ •ํ•ด ๋‘” ํ˜„์žฌ ์œ„์น˜ ๋ฐ›์•„์˜ค๊ธฐ
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ

    ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ ๋‚ด์šฉ
    ๋ฌธ์ œ ViewController์˜ viewDidLoad() ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์— locationManager.requestLocation()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ locationManager(didFailWithError:)๊ฐ€ ํ˜ธ์ถœ๋˜๋˜ ๋ฌธ์ œ
    ํ•ด๊ฒฐ ํ•™์Šต ๋‚ด์šฉ์ฒ˜๋Ÿผ CLLocationManager ํ• ๋‹น ์‹œ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ, ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ ์š”์ฒญ์„ ํ•˜๊ธฐ ์ „์— ์œ„์น˜ ์ •๋ณด๋ฅผ ์š”์ฒญํ•˜๊ฒŒ ๋จ! ์ด๋กœ ์ธํ•ด location์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์—†์–ด์„œ error handling ๊ด€๋ จ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋จ!
    โญ๏ธ๊ถŒํ•œ์„ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ๋งŒ location์„ ํ˜ธ์ถœํ•˜๋„๋ก ๋ฆฌํŒฉํ† ๋ง
  • ์•„์‰ฌ์šด ์  ์ „๋ ฅ ์‚ฌ์šฉ์„ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ๋Š” ์„ค์ •์— ๋Œ€ํ•œ ํ•™์Šต์„ ์ถ”๊ฐ€๋กœ ์ง„ํ–‰ํ•˜์ง€ ๋ชปํ•ด์„œ ์•„์‰ฌ์› ์ง€๋งŒ, STEP 2-2์—์„œ ํ•จ๊ป˜ ํ•™์Šต ํ›„ ๋ฐ˜์˜ํ•˜๊ธฐ๋กœ ํ•จ!

6. URLComponent

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ํ•™์Šต ๋‚ด์šฉ
    • URLComponents ์ธ์Šคํ„ด์Šค๋Š” URL?ํƒ€์ž… ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง
    • URLQueryItem์€ key, value ํ˜•ํƒœ๋กœ ์ƒ์„ฑ
    • path์†์„ฑ์— String์„ append, queryItems์— [URLQueryItem]์„ ํ• ๋‹น ํ˜น์€ appendํ•ด์ฃผ๋ฉด ์ž๋™์œผ๋กœ url์— ์•Œ๋งž์€ ์–‘์‹์œผ๋กœ ์ถ”๊ฐ€๋จ
  • ์ ์šฉ ๊ณผ์ •
    • ์•„๋ž˜ ์ด์œ ๋กœ URLComponents๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๋ฆฌํŽ™ํ† ๋ง์— ๋„์ „
      1. ๊ธฐ์กด์— ๋น„ํ•ด ๋ฌธ์ž์—ด ๊ด€๋ จ ์—ฐ์‚ฐ์„ ์ค„์ด๊ณ  ๊ธฐ๋ณธ์ œ๊ณต ํƒ€์ž…์„ ํ™œ์šฉํ•˜๊ณ ์ž ํ•จ,
      2. URL์˜ ๊ตฌ์„ฑ์š”์†Œ์— ๋ณด๋‹ค ๊ตฌ์กฐ์ ์œผ๋กœ ์ ‘๊ทผํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค๋Š” ์žฅ์ ์„ ๊ณ ๋ ค
    • ์ ์šฉ ๋ฐฉ๋ฒ•
      1. baseURL์„ ๊ธฐ๋ฐ˜์œผ๋กœ URLComponents ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ํ•„์š”ํ•œ path, query ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์„ ์ถ”๊ฐ€ยทํ• ๋‹น
      2. ์™„์„ฑ๋œ ์ธ์Šคํ„ด์Šค์˜ url์„ ์˜ต์…”๋„๋ฐ”์ธ๋”ฉํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ๋˜์ง€๊ฑฐ๋‚˜ url(URLํƒ€์ž…)์„ ๋ฐ˜ํ™˜
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ
    ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ ๋‚ด์šฉ
    ๊ธฐ์กด URLComponents์ธ์Šคํ„ด์Šค๋ฅผ static ํ”„๋กœํผํ‹ฐ๋กœ ์„ ์–ธ, path๋Š” ํ•ด๋‹น ์ธ์Šคํ„ด์Šค.path.append("String")ํ•ด์ฃผ๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„
    ๋ฌธ์ œ static ํ”„๋กœํผํ‹ฐ๋‹ค ๋ณด๋‹ˆ, WeatherParser.make(at:weatherRange:) ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค path๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๊ณ  ๋ง๋ถ™์—ฌ์ง€๋Š”(append) ๋ฌธ์ œ
    ํ•ด๊ฒฐ static ํ”„๋กœํผํ‹ฐ๋กœ๋Š” URLComponents ์ƒ์„ฑ์ž์— ํ•„์š”ํ•œ baseURL(String) ํ˜•ํƒœ๋งŒ ์ €์žฅ, ๋ฉ”์„œ๋“œ body ๋‚ด์—์„œ URLComponents ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์“ฐ๋„๋ก ์ˆ˜์ •

7. HTTP Method

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ํ•™์Šต ๋‚ด์šฉ

    • httpMethod
    • URLRequest & NSURLRequest
      • ๋กœ๋“œ ์š”์ฒญ์— ๋Œ€ํ•œ ๋‘ ๊ฐ€์ง€ ํ•„์ˆ˜ ์†์„ฑ์„ ์บก์ˆ ํ™”ํ•จ
        • ๋กœ๋“œํ•  URL
        • ์‚ฌ์šฉ๋˜๋Š” ์ •์ฑ…
      • HTTP/HTTPS ์š”์ฒญ์˜ ๊ฒฝ์šฐ HTTP method(GET, POST...)์™€ ํ—ค๋”๋ฅผ ํฌํ•จ
      • HTTP method๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•œ httpMethod ํ”„๋กœํผํ‹ฐ๋Š” NSURLRequest ํด๋ž˜์Šค์˜ ํ”„๋กœํผํ‹ฐ์ž„
      • Foundation ํ”„๋ ˆ์ž„์›Œํฌ๋Š” URLRequestํด๋ž˜์Šค์™€ ํ•ด๋‹น ๊ฐ€๋ณ€ ํด๋ž˜์Šค์ธ NSMutableURLRequest์— ์—ฐ๊ฒฐ๋œ URLRequest ๊ตฌ์กฐ์ฒด๋ฅผ ์ œ๊ณตํ•จ,
        ์ฆ‰, NSURLRequest์— ์žˆ๋Š” component๋“ค์„ URLRequest์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ!
      • httpMethod์˜ ๊ธฐ๋ณธ HTTP method๋Š” GET
  • ์ ์šฉ ๊ณผ์ •

    • ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด "GET"์ด default๊ฐ’
      The default HTTP method is โ€œGETโ€.
    • 'HTTP GET ๋ฉ”์„œ๋“œ ๋ช…์‹œ์  ํ˜ธ์ถœ'์ด ์š”๊ตฌ์‚ฌํ•ญ์ด๋ผ ์•„๋ž˜์™€ ๊ฐ™์ด setํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๊ธด ํ–ˆ์ง€๋งŒ, ์•„๋ž˜ ์•„์‰ฌ์šด ์ ๊ณผ ๋”๋ถˆ์–ด '๋ช…์‹œ์  ํ˜ธ์ถœ'์„ ์ œ๋Œ€๋กœ ๊ตฌํ˜„ํ•œ ๊ฒŒ ๋งž๋Š”๊ฐ€์— ๋Œ€ํ•œ ์˜๋ฌธ์ด ๋“ฆ
      request.httpMethod = "GET"
  • ์•„์‰ฌ์šด ์ 

    • ๋ฌธ์„œ์—์„œ ์•Œ ์ˆ˜ ์žˆ๋‹ค์‹œํ”ผ String? ํƒ€์ž…์ด๋ผ String("GET") ๋ฆฌํ„ฐ๋Ÿด๊ฐ’์„ ์ง์ ‘ ๋„ฃ์–ด์ค˜์•ผ ํ–ˆ์Œ
    • ํœด๋จผ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์šด ๋ถ€๋ถ„์ด๋ผ๊ณ  ์ƒ๊ฐ๋˜๋Š”๋ฐ ์›๋ž˜ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋งž๋Š” ๊ฑด์ง€, ๋†“์นœ ๋ถ€๋ถ„์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•จ

8. CLGeocoder

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ํ•™์Šต ๋‚ด์šฉ
    • CLGeocoder
      • Core Location ํ”„๋ ˆ์ž„์›Œํฌ ๋‚ด๋ถ€์˜ ํด๋ž˜์Šค
      • ์œ„๋„์™€ ๊ฒฝ๋„๋กœ ์ด๋ฃจ์–ด์ง„ ์ขŒํ‘œ์™€ ์‚ฌ์šฉ์ž ์นœํ™”์ ์ธ ์ฃผ์†Œ ํ‘œํ˜„ ์‚ฌ์ด์˜ ๋ณ€ํ™˜ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค
      • ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฑฐ๋ฆฌ, ๋„์‹œ, ์ฃผ, ๊ตญ๊ฐ€ ๋ฐ ์ง€์—ญ์ •๋ณด๋ฅผ ํฌํ•จํ•จ
      • forward geocoding method (์ˆœ๋ฐฉํ–ฅ)
        • ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ฃผ์†Œ๋กœ ์œ„๋„์™€ ๊ฒฝ๋„๋ฅผ ์ฐพ์Œ
        • ๊ด€์‹ฌ ์ง€์ ์ด๋‚˜ ํ•ด๋‹น ์œ„์น˜์˜ ๊ฑด๋ฌผ๊ณผ ๊ฐ™์€ ์ง€์ • ์œ„์น˜์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ
        • ์ œ๊ณต๋œ ์ •๋ณด๊ฐ€ ์—ฌ๋Ÿฌ ์œ„์น˜๋ฅผ ์‚ฐ์ถœํ•  ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ๊ฐœ์˜ placemark๊ฐ€ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์Œ
      • reverse geocoding method (์—ญ๋ฐฉํ–ฅ) โœ…
        • ์œ„๋„์™€ ๊ฒฝ๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ฃผ์†Œ๋ฅผ ์ฐพ์Œ
        • reverseGeocodeLocation ์‚ฌ์šฉ
      • forward / reverse ๋ชจ๋‘ CLPlacemark ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜
    • CLPlacemark
      • ์žฅ์†Œ์˜ ์ด๋ฆ„, ์ฃผ์†Œ ๋ฐ ๊ธฐํƒ€ ๊ด€๋ จ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ์ขŒํ‘œ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์นœํ™”์ ์ธ ์„ค๋ช…
      • ์ง€์ •๋œ ์œ„/๊ฒฝ๋„์— ๋Œ€ํ•œ placemark ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ
      • ์ขŒํ‘œ, ๊ตญ๊ฐ€, ์ง€์—ญ, ์ฃผ, ๋„์‹œ ๋ฐ ๊ฑฐ๋ฆฌ ์ฃผ์†Œ์™€ ๊ฐ™์€ ์ •๋ณด ํฌํ•จ
      • ๊ด€์‹ฌ์ง€์  ๋ฐ ์ง€๋ฆฌ์ ์ธ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Œ
      • reverse geocoding์„ ํ•˜๋Š” ๊ฒฝ์šฐ CLPlacemark ๊ฐœ์ฒด๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์Œ
      • Detail properties
        ํ”„๋กœํผํ‹ฐ๋ช… ์„ค๋ช…
        throughfare The street address associated with the placemark.
        ๊ฑฐ๋ฆฌ ์ฃผ์†Œ(๋„๋กœ๋ช…์ฃผ์†Œ์˜ ~๋กœ)
        subThroughfare Additional street-level information for the placemark.
        ์ถ”๊ฐ€ ๊ฑฐ๋ฆฌ์ˆ˜์ค€ ์ •๋ณด(์ƒ์„ธ์ฃผ์†Œ)
        locality The city associated with the placemark.
        ๋„์‹œ('์‹œ'๋กœ ๋๋‚˜๋Š” ํ–‰์ •๊ตฌ์—ญ)
        subLocality Additional city-level information for the placemark.
        ์ถ”๊ฐ€ ๋„์‹œ์ˆ˜์ค€ ์ •๋ณด(๋™/๋ฉด/~๋กœ)
        adminstrativeArea The state or province associated with the placemark.
        ์ฃผ ํ˜น์€ ์ง€๋ฐฉ ์ •๋ณด(ํ–‰์ •๊ตฌ์—ญ ์ค‘ ๊ฐ€์žฅ ๋„“์€ ๋ฒ”์œ„, ๋„/ํŠน๋ณ„์‹œ/๊ด‘์—ญ์‹œ)
        subAdminstrativeArea Additional administrative area information for the placemark.
        ์ถ”๊ฐ€ ํ–‰์ •๊ตฌ์—ญ ์ •๋ณด(ํ–‰์ •๊ตฌ์—ญ ์ค‘ ๊ตฐ)
        postalCode The postal code associated with the placemark.
        ์šฐํŽธ๋ฒˆํ˜ธ
        country The name of the country or region associated with the placemark.
        ๊ตญ๊ฐ€๋ช…
        name The name of the placemark.
        placemark์˜ ์ด๋ฆ„(๋ณดํ†ต throughfare + subThroughfare)
  • ์ ์šฉ ๊ณผ์ •
    • CLLocationManager์œผ๋กœ ๊ฐ€์ ธ์˜จ CLLocation ํƒ€์ž…์˜ location์œผ๋กœ reverse geocoding ์„ ์ง„ํ–‰
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ
    ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ ๋‚ด์šฉ
    ๋ฌธ์ œ ๊ธฐ์กด์— Coustom Location์œผ๋กœ ์ง€์ •ํ•œ ์ขŒํ‘œ(37.53, 126.96)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ฃผ์†Œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ '๊ตฌ'์— ํ•ด๋‹นํ•˜๋Š” '์šฉ์‚ฐ๊ตฌ'๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์Œ
    ํ•ด๊ฒฐ ํ•ด๊ฒฐ์ค‘!! ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ œ์•ฝ๋œ ์ƒํ™ฉ์ด๋ผ ์ถœ๋ ฅ๋œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ๊ฐ€๊ณตํ•ด์•ผ ํ•˜๋Š”์ง€ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด๋Š” ์ค‘

9. UICollectionViewCompositionalLayout

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ํ•™์Šต ๋‚ด์šฉ
    • UICollectionViewCompositionalLayout
      • Collection View ๋ ˆ์ด์•„์›ƒ์˜ ํ•œ ์ข…๋ฅ˜
      • ์ ์‘์„ฑ์ด ๋†’๊ณ  ์œ ์—ฐํ•œ ๋ฐฐ์—ด๋กœ ์•„์ดํ…œ์„ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ ˆ์ด์•„์›ƒ ๊ฐœ์ฒด
      • list(using:) ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ์‹œ ์ง€์ •๋œ ๊ตฌ์„ฑ์˜ list ์„น์…˜๋งŒ ํฌํ•จํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ์„ ๊ตฌ์„ฑ
      • ์œ„ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” UICollectionLayoutListConfiguration์œผ๋กœ layout์„ ๊ตฌ์„ฑํ•ด ์ฃผ์–ด์•ผ ํ•จ
    • UICollectionLayoutListConfiguration
      • list์˜ header์™€ footer๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ตฌ์กฐ์ฒด
      • headerMode, footerMode ํ”„๋กœํผํ‹ฐ๋ฅผ .supplementary๋กœ ์„ค์ •ํ•˜์—ฌ ๋ณด์กฐ view๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ header, footer ํ‘œ์‹œ ๊ฐ€๋Šฅ
      • ์œ„ ํ”„๋กœํผํ‹ฐ๋“ค์€ .none์ด ๊ธฐ๋ณธ๊ฐ’, headerMode์˜ ๊ฒฝ์šฐ .firstItemInSection์œผ๋กœ Section ๋‚ด์˜ ์ฒซ ๋ฒˆ์งธ ์•„์ดํ…œ์„ ํ—ค๋”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
      • backgroundColor๋Š” ๋ฐฐ๊ฒฝ์ƒ‰์„ ์™„์ „ํžˆ ์—†์• ๊ธฐ ์œ„ํ•œ ํ”„๋กœํผํ‹ฐ
        • ๊ธฐ๋ณธ ๊ฐ’์€ nil์ด์ง€๋งŒ, ์ด๋Š” system background color๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ โ†’ ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” white๋กœ ์ง€์ •๋จ
      • appearance๋กœ list์˜ ๋ชจ์–‘์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Œ
    • UICollectionViewListCell
      • list ๊ธฐ๋Šฅ๊ณผ ๊ธฐ๋ณธ ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” Collection View cell ํด๋ž˜์Šค
      • list์˜ ์…€ ์•ก์„ธ์„œ๋ฆฌ๋‚˜ ์ƒํ˜ธ์ž‘์šฉ ๋™์ž‘ ๋“ฑ์„ ์ง€์›ํ•˜๋Š” ํƒ€์ž…
    • UIBackgroundConfiguration
      • View์— ๋Œ€ํ•ด ๋ฐฐ๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๋Š” ํƒ€์ž…
      • UIButton์— ์ง์ ‘ ์ ์šฉํ•˜๊ฑฐ๋‚˜ UICollectionView/UITableView์˜ cell, header, footer์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • ์ ์šฉ ๊ณผ์ •
    • FlowLayout์—์„œ CompositionalLayout์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ๊ณผ์ •์—์„œ UICollectionViewCell ๋Œ€์‹  UICollectionViewListCell์œผ๋กœ ๋Œ€์ฒดํ•˜๋ ค๊ณ  ํ•˜์˜€์œผ๋‚˜ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ๋Š” list์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ผ์ด ์—†์œผ๋ฏ€๋กœ ํ•™์Šต๋งŒ ์ง„ํ–‰
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ
    • View์˜ backgroundColor๋ฅผ .clear๋กœ ์„ค์ •ํ•˜์˜€์œผ๋‚˜ ๋ฐฐ๊ฒฝ์ƒ‰์ด ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ
    • View๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” configuration์˜ backgroundColor๋ฅผ .clear๋กœ ํ•ด์ฃผ์–ด์•ผ ๋ฐฐ๊ฒฝ์ƒ‰์ด ์‚ฌ๋ผ์ง
  • ์•„์‰ฌ์šด ์ 
    • defaultContentConfiguration()์„ ํ™œ์šฉํ•˜์—ฌ ์…€์„ ๊ตฌ์„ฑํ•ด๋ณด์ง€ ๋ชปํ•œ ๊ฒƒ์ด ์กฐ๊ธˆ ์•„์‰ฌ์›€

10. URLComponents

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ์ ์šฉ ๊ณผ์ •

    • ๊ธฐ์กด) ๋‚ ์”จ ๋ฐ์ดํ„ฐ/์•„์ด์ฝ˜ ์ค‘ ๋ฌด์—‡์„ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•œ url์ด๋ƒ์— ๋”ฐ๋ผ URL ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ ๋‹ฌ๋ผ์ ธ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๋Ÿฟ ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ •์—์„œ ์ค‘๋ณตํ‘œํ˜„์ด ๋‹ค์ˆ˜ ๋ฐœ์ƒ
    • ์ˆ˜์ •)
      • ๊ธฐ์กด์—๋Š” path, queryItems ํ”„๋กœํผํ‹ฐ๋งŒ ํ™œ์šฉํ–ˆ์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” scheme, host ๋“ฑ ๋‹ค๋ฅธ url์š”์†Œ๋„ ์ ๊ทน์ ์œผ๋กœ ๋‹ค๋ค„๋ณด๊ธฐ๋กœ ํ•จ
      • ๋ฐ์ดํ„ฐ/์•„์ด์ฝ˜์„ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ ๊ฐ๊ฐ์—์„œ path, queryItems๋ฅผ ์ง์ ‘ ํ• ๋‹นํ•ด์คฌ๋˜ ๊ธฐ์กด ์ฝ”๋“œ๊ฐ€ OCP์— ์ข‹์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จ, ๋ถˆ๋Ÿฌ์˜ฌ ํƒ€์ž…์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ url์š”์†Œ๋“ค(scheme, host, path, query ๋“ฑ)์„ ๊ณ„์‚ฐ์†์„ฑ์œผ๋กœ ์•Œ๋ ค์ฃผ๋Š” WeatherRouter ์—ด๊ฑฐํ˜•์„ ๊ตฌํ˜„
      • URL ๋ฐ URLRequest๋ฅผ ๋งŒ๋“œ๋Š” ๊ธฐ๋Šฅ์€ ์—ฐ๊ด€์„ฑ์ด ๊นŠ์€ WeatherRouter์— ๋งก๊ธฐ๊ณ , ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ธฐ๋Šฅ๋งŒ WeatherParser์— ๊ตฌํ˜„
  • ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ

    ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… A ์ œ๋„ค๋ฆญํƒ€์ž… ๋ช…์‹œ ๋ฌธ์ œ
    ๐Ÿ˜ฐ - ๋ถˆ๋Ÿฌ์˜ฌ ํƒ€์ž…์— ๋”ฐ๋ฅธ ์ค‘๋ณต๋กœ์ง์„ ์ตœ๋Œ€ํ•œ ํ†ตํ•ฉํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜, ์–ด๋””๊นŒ์ง€๋‚˜ url์ƒ์„ฑ ๋ฐ ๋ณ€ํ™˜์„ ์œ„ํ•œ ์ •๋ณด๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•ด์ค˜์•ผ ํ•˜๋ฏ€๋กœ ์ œ๋„ค๋ฆญํƒ€์ž… ๊ด€๋ จ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒ
    - WeatherParser์—์„œ ๋‚ ์”จ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ๋‚ ์”จ์•„์ด์ฝ˜์„ parseํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” WeatherParser์˜ ์ œ๋„ค๋ฆญํƒ€์ž… T์˜ ์ •๋ณด๋ฅผ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š์Œ์—๋„ ํ˜ธ์ถœ๋ถ€์—์„œ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๋„ฃ์–ด์ค˜์•ผ ํ–ˆ์œผ๋ฏ€๋กœ ๋ถˆํ•„์š”&์ ์ ˆ์น˜ ์•Š์€ ๋น„์šฉ์„ ๋ฐœ์ƒ์‹œํ‚ด
    ๐Ÿš€ - WeatherParserํƒ€์ž…์ด ์•„๋‹Œ, ๋‚ ์”จ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฉ”์„œ๋“œ์—๋งŒ ๋‹จ๋…์œผ๋กœ ์ œ๋„ค๋ฆญํƒ€์ž…์„ ๋ถ™์ด๊ธฐ๋กœ ํ•จ
    ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… B ์ œ๋„ค๋ฆญํƒ€์ž… ์ถ”๋ก  ๋ฌธ์ œ
    ๐Ÿ˜ฐ - ์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ์˜ ํ˜ธ์ถœ๋ถ€์—์„œ ์ œ๋„ค๋ฆญํƒ€์ž…์„ ์ถ”๋ก ํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ์„œ๋ฅผ ์š”๊ตฌ
    - ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ํ˜•์„ ๋‹ด์„ ์ƒ์ˆ˜์— ํƒ€์ž…์„ ๋ช…์‹œํ•˜๋ ค ํ–ˆ์œผ๋‚˜, ํ˜‘์—…์ธ์›์ด ๋Š˜์–ด๋‚˜๊ณ  ์ด๋Ÿฌํ•œ ์œ ์˜์‚ฌํ•ญ์˜ ๊ณต์œ ๊ฐ€ ํ™œ๋ฐœํ•˜์ง€ ์•Š๋‹ค๋ฉด ์ด๋ฅผ ๋†“์ณ ํœด๋จผ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์—ฌ์ง€๊ฐ€ ํฌ๋‹ค๋Š” ์šฐ๋ ค ๋ฐœ์ƒ
    ๐Ÿš€ - ์ œ๋„ค๋ฆญํƒ€์ž… T์˜ ์ถ”๋ก ์„ ์œ„ํ•œ ๋‹จ์„œ(T.Type)๋ฅผ ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋„๋ก ๊ฐ•์ œํ•จ์œผ๋กœ์จ ์œ„์˜ ์šฐ๋ ค๋ฅผ ํ•ด๊ฒฐ
  • ์•„์‰ฌ์šด ์ 

    • host ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ ๋งจ์•ž์˜ "api." ์™ธ์—๋Š” ๋ชจ๋‘ ๋™์ผํ•จ
    • ์•„๋ž˜ 3๊ฐ€์ง€๋ฅผ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ 3๋ฒˆ์„ ํƒํ–ˆ์ง€๋งŒ, ์—ฌ์ „ํžˆ ์ค‘๋ณตํ‘œํ˜„์ด ๋งŽ์•„ ์ข‹์€ ๋ฐฉ๋ฒ•์ธ์ง€ ํ™•์‹ ์ด ์„œ์ง€ ์•Š์Œ
      1. 'api.'๋ฅผ ์ œ์™ธํ•œ ๋ถ€๋ถ„(openweathermap.org)์„ ๊ณตํ†ต์ƒ์ˆ˜๋กœ ์„ ์–ธ ํ›„, ํ•œ์ชฝ์—๋งŒ 'api.'๋ฅผ ๋ถ™์—ฌ host์— ํ• ๋‹นํ•˜๋Š” ๋ฐฉ๋ฒ•,
      2. subhost: String ๊ณ„์‚ฐ์†์„ฑ์„ ๋งŒ๋“ค์–ด ํ•œ์ชฝ์€ "api.", ํ•œ์ชฝ์€ ""๋ฅผ ๋„ฃ์€ ํ›„ host = subhost + host ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•,
      3. ํ•œ์ชฝ์€ "api.openorg", ํ•œ์ชฝ์€ "openorg"์„ host์— ํ• ๋‹นํ•˜๋Š” ๋ฐฉ๋ฒ•

11. UIRefreshControl

๐Ÿ–‡๏ธใ€€์ฐธ๊ณ ํ•œ ๊ณต์‹๋ฌธ์„œ:

  • ํ•™์Šต ๋‚ด์šฉ
    • UIRefreshControl ์ธ์Šคํ„ด์Šค์— addTarget(_:action:for:)๋กœ action method๋ฅผ ๋”ํ•ด์ฃผ๋ฉด target์€ refreshControl์˜ beginRefreshing์„ ๊ฐ์ง€ํ•˜๊ณ  controlEvents๋ฅผ ์œ„ํ•ด selector์•ˆ์— ๋„ฃ์–ด ๋‘” objc๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•จ
    • UICollectionView ์ธ์Šคํ„ด์Šค๋Š” UIRefreshControl?ํƒ€์ž…์˜ refreshControlํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง (๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ๊ฐ’์ด nil์ด๋ฏ€๋กœ ์ƒˆ๋กœ์šด UIRefreshControl ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด addTargetํ•œ ํ›„ ํ• ๋‹นํ•ด์ค˜์•ผ ํ•จ)
  • ์ ์šฉ ๊ณผ์ •
    • configureRefreshControl() ๋ฉ”์„œ๋“œ ๋ฐ objc๋ฉ”์„œ๋“œ refreshCollectionView()๋ฅผ ViewController์— ๊ตฌํ˜„

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%