Jiseob Kim

iOS Developer

Swift - Alamofire์™€ Escaping

29 Jul 2018 » Swift

์ž์ฃผ ๋ฐ˜๋ณต๋˜๋Š” Alamofire๋ฅผ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์ž. feat.Escaping

Alamofire๋ผ๋Š” ์ข‹์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์“ฐ๋‹ค๊ฐ€ ๋ณด๋ฉด ์ƒˆ๋กœ์šด swiftํŒŒ์ผ์„ ๋งŒ๋“ค๋•Œ๋งˆ๋‹ค ๋ฐ˜๋ณต์ ์œผ๋กœ ์“ด๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค.

๊ทธ๋ž˜์„œ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค๋ฉด ์ข‹๊ฒ ๋‹ค! ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค๊ฐ€, ์กธ์—…์ž‘ํ’ˆ ๋‹น์‹œ ํฌ๊ธฐํ–ˆ๋‹ค.

ํฌ๊ธฐํ•œ ๊ณผ์ •์„ ๋ณด๊ธฐ์ „์— ์˜ค๋Š˜์˜ ๊ตฌ์กฐ ๋จผ์ €, ์ฒจ๋ถ€

์Šคํ† ๋ฆฌ๋ณด๋“œ๋„ ์‹ฌํ”Œ, ์ฝ”๋“œ๋„ ์‹ฌํ”Œ, ํ™”๋ฉด๋„ ์‹ฌํ”Œํ•œ ์ƒํƒœ์ด๋‹ค


์ฝ”๋“œ ๊ตฌ์„ฑ

  1. Alamofire๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด import
  2. ์‚ฌ์šฉ๋  ํ•จ์ˆ˜
  3. url์„ ์„ ์–ธ๊ณผ ์ดˆ๊ธฐํ™”
  4. ํ†ต์‹  ์„ฑ๊ณต์‹œ obj ๋ผ๋Š” ์ด๋ฆ„์˜ Anyํƒ€์ž…์„ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ถœ๋ ฅ
    • ์ถœ๋ ฅ ๊ฐ’: ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ
  5. Any ํƒ€์ž… ๋ฐ์ดํ„ฐ๋ฅผ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ์บ์ŠคํŒ…
  6. ํ•ด๋‹น ๋”•์…”๋„ˆ๋ฆฌ์ค‘ โ€˜textโ€™๋ผ๋Š” ํ‚ค์˜ ๋ฐ์ดํ„ฐ๋ฅผ Stringํ˜•์œผ๋กœ ์บ์ŠคํŒ…
    • ๊ฐ’: โ€œServer Textโ€๋ผ๋Š” ๋ฌธ์ž์—ด
  7. Label์— ์ ์šฉ

์ €๋ฒˆํŽธ์— ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…์„ ์ฐธ๊ณ ํ•˜๋ฉด ์•„์ฃผ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ.

์ฐธ๊ณ : Alamofire์™€ Codable

๊ทธ๋Ÿฐ๋ฐ, ๋งŒ์•ฝ ๋‹ค๋ฅธ ํ†ต์‹ ์„ ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด 2๋ฒˆ ๋ถ€๋ถ„์—์„œ ๊ต‰์žฅํžˆ ์ค‘๋ณต์ด ๋งŽ์ด ์ผ์–ด๋‚œ๋‹ค.

// ์š”์ฒญ
let request = Alamofire.request(url)
// ์‘๋‹ต
request.responseJSON { (response) in
// Switch๋ฌธ ์‚ฌ์šฉ
switch response.result {                      
    case .success(let obj):
        print(obj)
    case .failure(let e):
        print(e.localizedDescription)
    }
}

์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž,

  1. ์š”์ฒญ
  2. ์‘๋‹ต
  3. ๋ถ„๊ธฐ๋ฌธ

์ด๊ฒƒ๋“ค์€ ๋ถ„๋ช… ๋ฐ˜๋ณต์ด ๋œ๋‹ค.

์•ฑ์ •๋ณด, ์‚ฌ์šฉ์ž ์ •๋ณด, ๊ธฐํƒ€๋“ฑ๋“ฑ ํ†ต์‹ ํ• ๋•Œ๋งˆ๋‹ค ๋˜‘๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ณ์•ผํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” ์กธ์—…์ž‘ํ’ˆ ๋‹น์‹œ ๊ฐ„์†Œํ™” ์‹œํ‚ค๊ณ  ์‹ถ์—ˆ๋‹ค.

๋‚ด๊ฐ€ ํ•„์š”ํ•œ๊ฑด nsDic ์˜€์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์—ˆ๋‹ค.

(์ฃผ์˜: ์•ˆ๋˜๋Š” ์ฝ”๋“œ์ž„)

1๋ฒˆ์„ ๋ณด๋ฉด ์–ด๋–ค ํด๋ž˜์Šค๋ผ๋„ ์ ‘๊ทผํ• ์ˆ˜ ์žˆ๋Š” ์ „์—ญํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ๊ฑด return ๊ฐ’์ด ์กด์žฌํ•˜๋ฉฐ ํƒ€์ž…์€ NSDictionary? ์ด๋‹ค. ์œ„์— ์“ด๋ฐ”์™€ ๊ฐ™์ด ์›ํ•˜๋˜ nsDic์˜ ํƒ€์ž…์ด๋‹ค.

// 1-1. ํ•„์š”ํ•œ nsDic์ด ๋ ๊ฐ’
var returnValue: NSDictionary?

๋Œ๋ ค์ค„ ๊ฐ’์˜ ํƒ€์ž…์„ ์˜ต์…”๋„๋กœ ์ง€์ •ํ•ด์ฃผ๊ณ 

// 5. returnValue์— ์ง€์ •
returnValue = nsDic

ํ†ต์‹ ์„ ํ†ตํ•ด ๋ฐ›์•„์„œ ์บ์ŠคํŒ…ํ•œ nsDic ๊ฐ’์„ returnValue์˜ ๊ฐ’์œผ๋กœ ๋„ฃ์–ด์ฃผ๊ณ 

// 6. ๋Œ๋ ค์ฃผ๊ธฐ
return returnValue

6๋ฒˆ์—์„œ return ํ•ด์ค€๋‹ค!


์ด๊ฒŒ ๊ณผ์—ฐ ๋ ๊นŒ? ๊ฒฐ๋ก ์€ ์•ˆ๋œ๋‹ค

์œ„ ์ด๋ฏธ์ง€ ํ•˜๋‹จ์˜ ์ฝ˜์†”์ฐฝ์„ ๋ณด๋ฉด nil ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.


์™œ nil์ผ๊นŒ?

๊ทธ ๋‹น์‹œ ์ฐธ ๋ฉ˜๋ถ•์ด์—ˆ๋Š”๋ฐ, ์ •๋‹ต์€ ๊ฐ„๋‹จํ•˜๋‹ค. ํ†ต์‹ ์€ ์–ผ๋งˆ๋‚˜ ๊ฑธ๋ฆด์ง€ ๋ชจ๋ฅธ๋‹ค. ๋”ฐ๋ผ์„œ,๋น„๋™๊ธฐ๋กœ ์ง„ํ–‰๋˜์•ผํ•œ๋‹ค.


๋งŒ์•ฝ ๋น„๋™๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด??

์•ฑ์ž์ฒด๊ฐ€ ๋ฉˆ์ถฐ ๋ฒ„๋ฆด๊ฒƒ์ด๋‹ค. ์™œ๋ƒ๋ฉด ํ†ต์‹ ์ด ๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ์ˆœ์ฐจ์ ์œผ๋กœ ์ง„ํ–‰๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์‹œ๊ฐ„์ด ์ข€ ์ง€์—ฐ๋œ๋‹ค๋ฉด ์‚ฌ์šฉ์ž๋Š” ์•ฑ์ด ์ฃฝ์—ˆ๋‚˜? ๋ผ๊ณ  ์ƒ๊ฐ ํ• ๊ฒƒ์ด๋‹ค.

๋„ˆ๋Š” ํ†ต์‹ ํ•˜๊ณ  ๋๋‚˜๋ฉด ํ• ๊ฑฐ ํ•˜๊ณ ์™€ ๋‚˜๋Š” ํ•˜๋˜์ผ ๊ณ„์†ํ• ๊ฒŒ ์ด๋Ÿฐ ๋Š๋‚Œ์ด๋ž„๊นŒ?

๊ทธ๋ž˜์„œ nil์ด ๋ฐœ์ƒํ•œ๊ฒƒ์ด๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ๋Š๋ผ๊ธฐ์—” ์ถฉ๋ถ„ํžˆ ๋น ๋ฅธ์‹œ๊ฐ„์•ˆ์— ํ‘œํ˜„๋˜์—ˆ์ง€๋งŒ ์•„๋ž˜์ฝ”๋“œ๊ฐ€ ์ง„ํ–‰๋ ๋•Œ์ฏค์ด๋ฉด

return์€ ์ด๋ฏธ ๋๋‚œ ํ›„์ด๋‹ค.

// 5. returnValue์— ์ง€์ •
returnValue = nsDic // ์ด๋•Œ, ์ด๋ฏธ return์€ ์ง„ํ–‰๋œ ์ƒํƒœ. ์ฆ‰, ๋„ฃ์–ด๋ดค์ž ์†Œ์šฉ์ด ์—†๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด nsDic์„ return ๊ฐ’์œผ๋กœ ์ •ํ•ด์ฃผ๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ nsDic์„ return ํ•ด์ค€๋‹ค๋ฉด?

์•ˆ๋œ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ์‹์ด ํ•„์š”ํ•˜๋‹ค.


Escaping

์ฒ˜์Œ์—” ์ด ๋ฌธ๋ฒ•์— ๋Œ€ํ•ด ๋„๋ฌด์ง€ ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ”๋‹ค. ์กธ์—…์ž‘ํ’ˆํ• ๋‹น์‹œ์—๋„ ์ฐพ์•˜์—ˆ์ง€๋งŒ, ์‹œ๊ฐ„์ด ๊ธ‰ํ•ด์„œ ์กฐ๊ธˆ ์‹œ๋„ํ•ด๋ณด๋‹ค ํฌ๊ธฐํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ์•Œ๋ฉด ์ •๋ง ๋„์›€์ด ๋งŽ์ด ๋œ๋‹ค. ํ˜น์—ฌ๋‚˜ ์ฝ๋Š” ๋ถ„์ด ๊ณ„์‹œ๋‹ค๋ฉด ์ด๋ฆฌ ์ €๋ฆฌ ์‹œ๋„ํ•ด์„œ ๊ผญ ์„ฑ๊ณตํ•˜์‹œ๊ธธ.

์ผ๋‹จ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

ํŠน๋ณ„ํžˆ 0๋ฒˆ์ด๋ผ ์ผ๋‹ค. ์ฑ…์œผ๋กœ๋งŒ ๊ณต๋ถ€ํ–ˆ๋‹ค๋ฉด, ์ •๋ง ์ •๋ง ์ƒ์†Œํ•  ๋ชจ์Šต์ผ๊ฒƒ์ด๋‹ค.

func useEscaping(url: String, handler: (NSDictionary) -> Void) {}

ํ˜น์‹œ, ์ด๋Ÿฐ ๋ชจ์Šต์ด๋ฉด ์กฐ๊ธˆ์ด๋‚˜๋งˆ ์ต์ˆ™ํ•˜๋‹ค. ์Šค์œ„ํ”„ํŠธ๋Š” ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋ผ๊ณ ๋„ ๊ฐ€๋Šฅํ•œ๋ฐ, ๊ทธ ์ด์œ ๋Š” ์Šค์œ„ํ”„ํŠธ์—์„œ ํ•จ์ˆ˜๋Š” ์ผ๊ธ‰ํ•จ์ˆ˜์— ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์กฐ๊ฑด์ด ์žˆ์ง€๋งŒ ๋ณต์žกํ•˜๋‹ˆ, ๋‚˜์ค‘์— ๋” ์•Œ์•„๋ณด๋Š”๊ฑธ๋กœ ํ•˜๊ณ . ์—ฌ๊ธฐ์„œ ๊ด€๋ จ๋œ ์ผ๊ธ‰ ํ•จ์ˆ˜ ์กฐ๊ฑด๋“ค๋งŒ ๋งํ•ด๋ณด๋ฉด

  1. ์ธ์ž ๊ฐ’์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‘๊ฐ€์ง€ ์ •๋„? ์ €๊ธฐ์„œ handler ๋ผ๋Š” ์ธ์ž๋Š” ํƒ€์ž…์ด NSDictionary๋งŒ ๋ฐ›๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ return์ด ์žˆ๋‹ค. ์ด๊ฑด ๋ˆ„๊ฐ€๋ด๋„ ํ•จ์ˆ˜๋‹ค. ์ด๋Ÿฐ์‹์œผ๋กœ ์ธ์ž๊ฐ’์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•˜๋‹ค. ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ๋„ ๊ฐ€๋Šฅํ•˜๊ณ ! ์ผ๊ธ‰ํ•จ์ˆ˜๋ž€ ํ‘œํ˜„๋„ ์ค‘์š”ํ•˜์ง€๋งŒ ๊ทธ ๋‚ด์šฉ์ธ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•˜๋‹ค๋Š”๊ฒŒ ์ค‘์š”ํ•˜๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด @escaping ์ด ์˜๋ฏธํ•˜๋Š”๊ฒƒ์€ ๋ฌด์—‡์ผ๊นŒ

handler ๋ผ๋Š” ํ‘œํ˜„์€ ๋ณดํ†ต โ€˜๋‹ค๋ฃจ๋‹คโ€™๋กœ ์‚ฌ์šฉ๋˜๊ณ  stackOverFlow ๊ฐ™์€ ๊ณณ์—์„œ ๋ณด๋ฉด

๊ด€๋ จ ์ž๋ฃŒ์—์„œ ์ข…์ข… ์ธ์ž๊ฐ’์— completionHandler , completion๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋งŽ์ด ์“ฐ๋Š”๋ฐ,

์ด๋Š” ์™„๋ฃŒํ›„ ์ฒ˜๋ฆฌํ•  ์ž‘์—…, ์™„๋ฃŒํ›„ ๋‹ค๋ฃฐ๊ฒƒ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์ข€๋” ํŽธํ–ˆ๋˜๊ฒƒ ๊ฐ™๋‹ค.


@escaping

์ด๋ฆ„๋ถ€ํ„ฐ๊ฐ€ ํƒˆ์ถœ์ด๋‹ค. ๋‚˜๋Š” ์ด๋ ‡๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์žˆ๋‹ค. ํ˜„์žฌ ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ ๋„๋ง์ณ ๋‚˜์˜จ๋‹ค. ํ•˜์ง€๋งŒ, ๊ทธ๋•Œ NSDictionary๋ฅผ ๊ฐ€์ง€๊ณ  ๋„๋ง์นœ๋‹ค. ์ด๊ฒŒ ํฌ์ธํŠธ๋‹ค, ๋‹ค๋ฅด์ง€๋งŒ ๋น„์Šทํ•˜๊ฒŒ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š”๊ฑด, NSDictionary ๊ฐ’์„ ๋ฆฌํ„ดํ•ด์ค€๋‹ค๊ณ ๋„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์“ฐ๋Š” ๋ฐฉ์‹์€ ์ด๋ฏธ ๋งŽ์ด๋“ค ์ ‘ํ–ˆ์„ ๊ฒƒ์ด๋‹ค. ๋น„์Šทํ•œ ๋ฌธ๋ฒ•์„ ๋ณด์ž

1๋ฒˆ์˜ ๊ฒฝ์šฐ๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ๋ฒ•์ด๋‹ค.

2๋ฒˆ์˜ ๊ฒฝ์šฐ ํฌ์ŠคํŒ…์— ์ž์ฃผ ๋‚˜์˜จ Alamofire์—์„œ ์‘๋‹ต ๊ฐ’์„ ๋ฐ›์•˜์„๋•Œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ๋‚˜์˜จ๊ฒƒ์ด๋‹ค.

์ €๋Ÿฐ ๋ฌธ๋ฒ•์„ ๋งŒ๋“ค๋ ค๋ฉด ํ•„์š”ํ•œ๊ฒƒ์€ @escaping์„ ์“ฐ๋Š” ๊ฒƒ์ด๋ผ๋Š” ๊ฒฐ๋ก ์ด ๋‚˜์™”๋‹ค!

๊ฐ๊ฐ์˜ ์ฐจ์ด์ ์„ ๋ณด์ž

// 1. Animation ( ์ธ์ž: o , ๋ฐ˜ํ™˜: x)
((Bool)-> Void)?
// 2. Alamofire Response ( ์ธ์ž: o , ๋ฐ˜ํ™˜: x)
(DataResponse<Any>) -> Void)
// 3. Use Escaping ( ์ธ์ž: o , ๋ฐ˜ํ™˜: x)
(NSDictionary -> Void)


์‰ฌ์šด ์ˆœ์„œ๋Œ€๋กœ ์ •๋ฆฌํ–ˆ๋‹ค. ๊ณตํ†ต์ ์€ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์ „๋ถ€ ์—†๋‹ค๋Š”๊ฒƒ.

UIView Animation

1๋ฒˆ์˜ ๊ฒฝ์šฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‚ฌ์šฉํ• ๋•Œ ์ƒ๊ฐ์„ ํ•ด๋ณด์ž,

UIView.animate(withDuration: 2, animations: {
    self.view.alpha = 0
}) { (value) in
    if value == true {
        print("success")
    }
}

์ž์‹ ์ด ์ •ํ•œ ์‹œ๊ฐ„(์—ฌ๊ธฐ์„  2์ดˆ)๋™์•ˆ animations ์˜ ๋‚ด์šฉ์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ž‘์—…์ด ๋๋‚œ๋’ค์— ํ• ์ผ์€ completion๋‚ด์šฉ์ด ๋œ๋‹ค. ์ €๊ธฐ์„œ ๋’ค์— ๋ฌผ์Œํ‘œ๊ฐ€ ๋ถ™์–ด์žˆ๋Š”๋ฐ, nil์ด ๋ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰ ํšจ๊ณผ๋งŒ ์ฃผ๊ณ  ๊ทธ๋’ค์— ๋‹ค๋ฅธ ์ž‘์—…์€ ์•ˆํ•ด๋„ ๋œ๋‹ค๋Š”๊ฒƒ! ๊ทธ๋ ‡๊ธฐ์— animation์— ๋” ๋“ค์–ด๊ฐ€๋ณด๋ฉด default๊ฐ’์œผ๋กœ nil์ด ๋“ค์–ด๊ฐ€์žˆ๋‹ค.


Alamofire Response

๋‹ค์‹œ ๋ณธ๋ก ์œผ๋กœ ๋“ค์–ด๊ฐ€์„œ 2๋ฒˆ์งธ ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด DataResponse๋ผ๋Š” ๊ฒƒ์ด๊ณ  ๋’ค์— ๊บฝ์‡ ๋กœ ๋œ๊ฑด Generic์„ ์˜๋ฏธํ•œ๋‹ค.

Generic๋„ ๋‚˜์ค‘์— ๋‹ค๋ฃจ๊ธฐ๋กœํ•˜๊ณ , ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค ๊ตฌ์กฐ์ฒด ๋“ฑ๋“ฑ ํ•˜๋‚˜ ์„ ์–ธํ•ด์„œ ์—ฌ๋Ÿฌ ํƒ€์ž…(String, Int ๋“ฑ๋“ฑ)์„ ๋Œ€์‘ ํ•œ๋‹ค ์ƒ๊ฐํ•˜๊ณ  ๋„˜์–ด๊ฐ€์ž.

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ๊ฑด, ํ†ต์‹  ํ›„ DataResponse๋ผ๋Š” ํƒ€์ž…์„ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์„œ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ–ˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ด๊ฒŒ ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ๊ฒƒ์ด๋‹ค. nsDictionary๋กœ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์„œ ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ด๋‹ค.


Escaping

์‚ฌ์šฉ๋ฒ•์€ ์œ„์˜ Alamofire๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๋‹จํ•˜๋‹ค.

2-2 ๋ถ€๋ถ„์ด ์ „๋ถ€์ด๋‹ค. ๋ฐ›์•„์˜จ NSDictionary ํƒ€์ž…์„ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ ์ด๋ฆ„์„ nsDic ์ด๋ผ ์ด๋ฆ„์„ ๋ถ™์—ฌ์ฃผ๊ณ  ์ •๋ง ๋”•์…”๋„ˆ๋ฆฌ ์‚ฌ์šฉํ•˜๋“ฏ ์‚ฌ์šฉํ•˜๋ฉด ๋์ด๋‹ค.

๊ทธ ์•„๋ž˜์— ์“ด๊ฒƒ์€ ์œ„์—์„œ ์‹คํŒจํ–ˆ๋˜ ๋ฐฉ์‹์ธ NSDictionary๋ฅผ return ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์˜ ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉ ํ•œ๊ฒƒ์ด๋‹ค.

๊ทผ๋ฐ ์•„๋ž˜ ์ฝ˜์†”์ฐฝ์„ ๋ณด๋ฉด ๋‹น์—ฐํ•˜์ง€๋งŒ ์žฌ๋ฏธ๋‚œ ์ถœ๋ ฅ๋ฌผ์ด ๋ณด์ธ๋‹ค.

์‚ฌ์šฉํ•œ๊ฑด escaping ๋ฐฉ์‹์ด ๋จผ์ €์ง€๋งŒ, ์ถœ๋ ฅ๋œ๊ฑด return ๋ฐฉ์‹์„ ์‚ฌ์šฉ ํ•œ๊ฒƒ์ด ๋จผ์ €์ด๋‹ค. ์ด์ œ๋Š” ๋‹น์—ฐํ•˜๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค๊ฒƒ์ด๋‹ค.

๋„คํŠธ์›Œํฌ๊ฐ€ ์•„๋ฌด๋ฆฌ ๋น ๋ฅด๋‹ค ํ•œ๋“ค ๋กœ์ปฌ์˜ ์ฝ”๋“œ์ง„ํ–‰๋ณด๋‹ค ๋น ๋ฅผ๋ฆฌ๊ฐ€โ€ฆ ๊ทธ๋ฆฌ๊ณ  ๋น„๋™๊ธฐ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ์ผ!


๋ฒˆ์™ธ: ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š”๊ฑด ์ข‹๋‹ค! ๊ทธ๋ ‡์ง€๋งŒ, ํ†ต์‹  ์‹คํŒจ์‹œ์—” ๋‹ค๋ฅด๊ฒŒ ๋Œ€์‘ํ•˜๊ณ  ์‹ถ์€๋ฐ? ํ•  ๊ฒฝ์šฐ

์œ„์— ์ž ์‹œ ์–ธ๊ธ‰ํ•œ ์ผ๊ธ‰ ํ•จ์ˆ˜์˜ ํŠน์ง•์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐ! ๋‚ด๊ฐ€ ํ•˜๊ณ  ์‹ถ์€ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ , ์‹คํŒจ์‹œ์— ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๋ฉด ๊ทธ๋งŒ

func useEscaping(url: String, whenIfFailed: (), handler: @escaping (NSDictionary) -> Void) {
    
    let request = Alamofire.request(url)
    
    request.responseJSON { (response) in
        switch response.result {
        case .success(let obj):
            guard let nsDic = obj as? NSDictionary else { return }
            handler(nsDic)
            
        case .failure(let e):
            // ํ†ต์‹  ์‹คํŒจ์‹œ
            print(e.localizedDescription)
            whenIfFailed
        }
    }
}

์œ„์™€ ๊ฐ™์ด ์ ์–ด ์ฃผ์ž. ํ•˜๋‚˜๊ฐ€ ์ถ”๊ฐ€ ๋˜์—ˆ๋‹ค. whenIfFailed ๋ผ๋Š” ํ•จ์ˆ˜ ํƒ€์ž…์˜ ์ธ์ž์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฃผ์„ ๋ถ€๋ถ„์— ๋ณด๋ฉด ํ†ต์‹  ์‹คํŒจ์‹œ ์ž‘๋™ํ•˜๊ฒŒ ๋˜์–ด ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ, ํ•ญ์ƒ ์‹คํŒจ์— ๋Œ€์‘ ํ• ํ•„์š”๊ฐ€ ์—†์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์œ„ ํ•จ์ˆ˜์•ˆ์— ๋™์ผํ•˜๊ฒŒ ๋Œ€์‘๋˜๊ฒŒ ์งœ๋‘”๋‹ค๋ฉด ๊ตณ์ด ๊ทธ๋Ÿด ํ•„์š” ์—†๋‹ค. ๊ทธ๋Ÿฌ๋‚˜! ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค! ๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ปํ•˜๋ฉด ์ข‹์„๊นŒ? whenIfFailed ๋ฅผ ์˜ต์…”๋„๋กœ ํ•ด์ฃผ๊ณ  ๊ธฐ๋ณธ๊ฐ’์„ nil๋กœ ํ•ด์ฃผ์ž

func useEscaping(url: String, whenIfFailed: (() -> Void)? = nil, handler: @escaping (NSDictionary) -> Void) {
    
    let request = Alamofire.request(url)
    
    request.responseJSON { (response) in
        switch response.result {
        case .success(let obj):
            
            guard let nsDic = obj as? NSDictionary else { return }
            handler(nsDic)
            
        case .failure(let e):
            
            // ํ†ต์‹  ์‹คํŒจ์‹œ
            print(e.localizedDescription)
            whenIfFailed?()
        }
    }
}

whenIfFailed ๋ถ€๋ถ„์ด ์ข€ ๋‹ฌ๋ผ์กŒ๋‹ค. (() -> Void) ๋Š” ๊ฐ™์€๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ๋’ค์— ๋ฌผ์Œํ‘œ๊ฐ€ ๋ถ™์–ด ์žˆ๊ณ , ๊ธฐ๋ณธ ๊ฐ’์ด nil ๋กœ ๋˜์–ด์žˆ๋‹ค.

์ฆ‰, ํ•„์š” ์—†์œผ๋ฉด ์•ˆ์จ๋‘ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ ๊ฒฐ๊ณผ ์•„๋ž˜์ชฝ์— ๋ณด๋ฉด whenIfFailed ์— ๋ฌผ์Œํ‘œ๊ฐ€ ๋ถ™์–ด์žˆ๊ณ , ์ด๋Š” nil์ด๋ฉด ์ž๋™์œผ๋กœ ์‹คํ–‰ ์•Š๊ณ  ์ง€๋‚˜๊ฐ€๊ฒŒ ๋œ๋‹ค!

์‚ฌ์šฉ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค

func ifFailed() {
    print("์‹คํŒจํ–ˆ์–ด์š”")
}

// ํ•จ์ˆ˜ ์‚ฌ์šฉ
useEscaping(url: url, whenIfFailed: ifFailed) { (nsDic) in
    guard let text = nsDic["text"] as? String else { return }
    print("(Escaping ์‚ฌ์šฉ)text: \(text)")
}

๊ทธ๋Ÿฐ๋ฐ, ๋‚˜๋Š” ๊ฐ๊ฐ์— ๋‹ค๋ฅด๊ฒŒ ๋ฐ˜์‘ํ• ๊ฑฐ์•ผ!! ๋ผ๊ณ  ํ•˜๋ฉด, ๊ฐ ํ•จ์ˆ˜ ๋งŒ๋“œ๋Š”๊ฒƒ๋„ ์ผ์ด๋‹ค. ๊ทธ๋Ÿด ๊ฒฝ์šฐ์—” ์ด๋ ‡๊ฒŒ ํ•ด๋ณด๋Š”๊ฑด ์–ด๋–จ๊นŒ

func useEscaping(url: String, whenIfFailed: @escaping () -> Void, handler: @escaping (NSDictionary) -> Void) {
    
    let request = Alamofire.request(url)
    
    request.responseJSON { (response) in
        switch response.result {
        case .success(let obj):
            
            guard let nsDic = obj as? NSDictionary else { return }
            handler(nsDic)
            
        case .failure(let e):
            
            // ํ†ต์‹  ์‹คํŒจ์‹œ
            print(e.localizedDescription)
            whenIfFailed()
        }
    }
}

์—ฌ๊ธฐ์„œ๋„ escaping์„ ์‚ฌ์šฉํ–ˆ๋‹ค. ๊ทธ๋Ÿผ ์‚ฌ์šฉ ์ฝ”๋“œ์—์„ ?

๋งˆ์น˜ UIView Animation ๊ฐ™๋‹ค.

๊ฐ’์„ ์ฑ„์›Œ ๋„ฃ์œผ๋ฉด ์ด๋ ‡๊ฒŒ

useEscaping(url: url, whenIfFailed: {
    print("์‹คํŒจํ–ˆ์–ด์š”")
}) { (nsDic) in
    guard let text = nsDic["text"] as? String else { return }
    print("(Escaping ์‚ฌ์šฉ)text: \(text)")
}

escaping์€ ์•Œ๋ฉด ์•Œ์ˆ˜๋ก ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ด๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์ข€ ๋” ํ™œ์šฉํ•  ๊ณณ์„ ์ฐพ์•„๋ด์•ผ๊ฒ ๋‹ค.