๐ 2019.11.07 (๋ชฉ)
WWDC 2015 | Session : 411 | Category : Swift
๐
Swift in Practice - WWDC 2015 - Videos - Apple Developer
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๋ ์ ํจํ ์ด๋ฆ ์ธ์ง ์๋์ง ๋ชจ๋ฆ!
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"
- 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 ํด์ค๋ค
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์ ํตํ ์ฌ์ฌ์ฉ
- ํธ๋ฆฌํ ๋ฌธ๋ฒ