Skip to content

Latest commit

ย 

History

History
195 lines (140 loc) ยท 5.89 KB

Swift-in-Practice.md

File metadata and controls

195 lines (140 loc) ยท 5.89 KB

Swift in Practice

๐Ÿ“… 2019.11.07 (๋ชฉ)

WWDC 2015 | Session : 411 | Category : Swift

๐Ÿ”—

Swift in Practice - WWDC 2015 - Videos - Apple Developer

Asset Catalog Identifiers

    let isabellaImage = UIImage(named: "Isabella")!
    
    let williamImage = UIImage(named: "William")!
    
    let oliviaImage = UIImage(named: "Olivia")!

์•ฑ์—์„œ Asset์— ์žˆ๋Š” ์ด๋ฏธ์ง€๋“ค์„ ์ด๋Ÿฐ ์‹์œผ๋กœ ์“ฐ๋ ค๋ฉด unwrap ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฏธ์ง€๋Š” 3๊ฐœ๊ฐ€ ์žˆ์ง€๋งŒ ์ฝ”๋“œ ๋‚ด๋ถ€์—์„œ ์–ผ๋งˆ๋‚˜ ๋งŽ์ด ์“ฐ์ด๊ณ  ์žˆ์„์ง€ ๋ชจ๋ฆ„

โ†’ String Constants

    let IsabellaUnicornImageName = "Isabella"
    
    let imsabellaImage = UIImage(named: IsabellaUnicornImageName)!

ํ•˜์ง€๋งŒ ์ด๊ฒƒ ๋˜ํ•œ unwrap ํ•ด์•ผ ํ•œ๋‹ค. compiler๋‚˜ framework๋Š” ์œ ํšจํ•œ ์ด๋ฆ„ ์ธ์ง€ ์•„๋‹Œ์ง€ ๋ชจ๋ฆ„!

String as Distinct Types

Strongly typed solution์ด ํ•„์š”

์š”๊ตฌ์‚ฌํ•ญ

  • String์„ ์ƒˆ๋กœ์šด ํƒ€์ž…์œผ๋กœ Mapping
  • ์ดˆ๊ธฐํ™” ์‹œ ์‹คํŒจ ํ•˜์ง€ ์•Š๋Š” UIImage

ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

application specific enumeration

    let isabellaImage = UIImage(assetIdentifier: .Isabella)
    
    let williamImage = UIImage(assetIdentifier: .William)
    
    let oliviaImage = UIImage(assetIdentifier: .Olivia)

์ด๋Ÿฐ ์‹์œผ๋กœ UIImage๋ฅผ ์ƒ์„ฑ ํ•  ๋•Œ๋งˆ๋‹ค enum์„ ์ „๋‹ฌํ•˜๊ณ , unwrap ํ•„์š” ์—†๊ฒŒ ํ•˜๊ณ  ์‹ถ์–ด

    extension UIImage {
    	enum AssetIdentifier: String {
    		case Isabella = "Isabella"
    		case William = "William"
    		case Olivia = "William"		
    	}
    }

์ด๋ ‡๊ฒŒ value๊ฐ€ ์ค‘๋ณต ๋  ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์—๋Ÿฌ๋ฅผ ์•Œ๋ ค์ค€๋‹ค. error: raw value for enum case is not unique

    let isabellaImage = UIImage(assetIdentifier: .Isabella)
    
    let williamImage = UIImage(assetIdentifier: .William)
    
    let oliviaImage = UIImage(assetIdentifier: .Oliia)

asset์ •๋ณด๋ฅผ structure๋กœ ์ฝ”๋“œ์— ํฌํ•จ ์‹œ์ผœ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด์ œ๋Š” ์˜คํƒ€๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์—๋Ÿฌ ์•Œ๋ ค์คŒ

error: 'UIImage.AssetIdentifier.Type' does not have a member name 'Oliia"

AssetIdentifier Enum Benefits

  • Centrally located constants : ์ด๋ฏธ์ง€ asset์ด ์ถ”๊ฐ€ ๋˜์—ˆ์„ ๋•Œ, ์–ด๋””์— constant๋ฅผ ์ถ”๊ฐ€ ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•จ
  • Doesn't pollute global namespace : global namespace๋ฅผ ๋”๋Ÿฝํžˆ์ง€ ์•Š๋Š”๋‹ค
  • Must use one of the enum cases : enum case ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค
  • Image initializers are not failbale : ์–ธ์ œ๋‚˜ non-optional image๋ฅผ return ํ•ด์ค€๋‹ค

Segue Identifiers

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    	switch segue.identifier {
    		case "ShowImportUnicorn"?: 
    		case "ShowCreateNewUnicorn"?: 
    		default: fatalError("Invalid segue identifier \(segue.identifier).")
    	}
    }

์Šคํ† ๋ฆฌ๋ณด๋“œ์— segue๋“ค์„ ์ •์˜ํ•ด ๋†“์•˜์–ด๋„ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ชฐ๋ผ

๊ทธ๋ž˜์„œ default ์•ˆ ๋„ฃ์–ด ์ฃผ๋ฉด error: switch mush be exhaustive, consider adding a default case

๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ์— segue๋ฅผ ์ถ”๊ฐ€ ํ•ด์ฃผ์—ˆ์„ ๋•Œ, ์–ด๋””์— ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ ํ•ด์•ผ ๋˜๋Š”์ง€ ํ•˜๋‚˜ํ•˜๋‚˜ ๋‹ค ์ฐพ์•„์•ผ ํ•จ

โ†’ enum์œผ๋กœ ํ•ด๊ฒฐ

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    	switch segue.identifier {
    		case "ShowImportUnicorn"?: 
    		case "ShowCreateNewUnicorn"?: 
    		default: fatalError("Invalid segue identifier \(segue.identifier).")
    	}
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    	guard let identifier = segue.identifier, segueIdentifier = SegueIdentifier(rawValue: identifier)
    	else { fatalError("Invalid segue identifier \(segue.identifier).") }
      
      switch segueIdentifier {
    		case .ShowImportUnicorn: 
    		case .ShowCreateNewUnicorn: 
    	} 
    }

segue ์ถ”๊ฐ€ ์‹œ์—, ์ฝ”๋“œ ์ถ”๊ฐ€ ์•ˆํ•ด ์ฃผ๋ฉด error: switch must be exhaustive, consider adding a default case ๊ฐ€ ๋œจ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋””์— ๋กœ์ง์„ ์—…๋ฐ์ดํŠธ ํ•ด์•ผํ•˜๋Š”์ง€ ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

    class UnicornBrowserViewController: UIViewController {
        func handleAction(sender: AnyObject?) {
    			performSegueWithIdentifier(.ShowImportUnicorn, sender: sender) 
    		}
    }

protocol์„ ์‚ฌ์šฉํ•ด ํ•˜๋‚˜์˜ implementation๋ฅผ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ViewController์—์„œ ๊ณ„์ธต์— ์ƒ๊ด€ ์—†์ด ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ViewController๋Š” ์•„๋ž˜ protocol์„ conformํ•ด์•ผํ•จ

    protocol SegueHandlerType {
        typealias SegueIdentifier: RawRepresentable
    }

    extension SegueHandlerType where Self: UIViewController, SegueIdentifier.RawValue == String {
    	func performSegueWithIdentifier(segueIdentifier: SegueIdentifier, sender: AnyObject?) { 
    		performSegueWithIdentifier(segueIdentifier.rawValue, sender: sender)
    	}
    }

์œ„์˜ ํ”„๋กœํ† ์ฝœ๋งŒ ViewController์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค!

    class UnicornBrowserViewController: UIViewController, SegueHandlerType {
        enum SegueIdentifier: String {
    		...
    	} 
    
    	func handleAction(sender: AnyObject?) {
    		performSegueWithIdentifier(.ShowImportUnicorn, sender: sender)
    	}
    }
    func segueIdentifierForSegue(segue: UIStoryboardSegue) -> SegueIdentifier {
    	guard let identifier = segue.identifier,
    	segueIdentifier = SegueIdentifier(rawValue: identifier)
    	else { 
    		fatalError("Invalid segue identifier \(segue.identifier).") }
        
    		return segueIdentifier
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        switch segueIdentifierForSegue(segue) {
    			case .ShowImportUnicorn: 
    			case .ShowCreateNewUnicorn: 
    		} 
    }

SegueHandlerType Protocol Benefits

  • ์ƒˆ๋กœ์šด segue๊ฐ€ ์ถ”๊ฐ€ ๋  ๋•Œ ๋งˆ๋‹ค ์•„์ง ํ•ด๋‹น segue๊ฐ€ ์ฒ˜๋ฆฌ ๋˜์ง€ ์•Š์•˜์œผ๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์—๋Ÿฌ๋ฅผ ์•Œ๋ ค์ค€๋‹ค
  • protocol์„ ํ†ตํ•œ ์žฌ์‚ฌ์šฉ
  • ํŽธ๋ฆฌํ•œ ๋ฌธ๋ฒ•