Securely store small chunks of data on behalf of the user.
The keychain services API helps you solve this problem by giving your app a mechanism to store small bits of user data in an encrypted database called a keychain.
The keychain is not limited to passwords, as shown in Figure 1. You can store other secrets that the user explicitly cares about, such as credit card information or even short notes. You can also store items that the user needs but may not be aware of. For example, the cryptographic keys and certificates that you manage with Certificate, Key, and Trust Services enable the user to engage in secure communications and to establish trust with other users and devices. You use the keychain to store these items as well.
Article Storing Keys in the Keychain
guard <조건식 또는 표현식> else {
<조건식 또는 표현식의 결과가 false일 때 실행될 코드>
}
= 특정 조건을 만족하지 않은 채로 후속 코드를 실행하면 심각한 오류가 발생할 경우에, 전체 구문을 조기 종료(Early Exit)하기 위한 목적으로 사용됨
import Foundation
func divide(base: Int) {
let result = 100 / base
print(result)
}
입력받은 값을 받아 100을 나누기
단! 0으로 나눌 경우에는 오류가 발생함
이런 경우를 방지하기 위해 다음과 같이 guard 구문 사용 가능
func divide(base: Int) {
guard base != 0 else {
print("연산할 수 없습니다.")
return
}
let result = 100 / base
print(result)
}
divide(base: 0) // 연산할 수 없습니다.
divide(base: 5) // 20
if문으로 바꾸면 아래와 같이 조건식이 반대로 바뀜
func divide(base: Int) {
if base == 0 {
print("연산할 수 없습니다.")
return
}
let result = 100 / base
print(result)
}
guard 구문을 이용하여 인자값을 다양한 조건으로 필터링하는 코드
import Foundation
func divide(base: Int) {
guard base != 0 else {
print("연산할 수 없습니다.")
return
}
guard base > 0 else {
print("base는 0보다 커야 합니다.")
return
}
guard base < 100 else {
print("base는 100보다 작아야 합니다.")
return
}
let result = (100 / base)
print(result)
}
divide(base: -1) // base는 0보다 커야 합니다.
divide(base: 200) // base는 100보다 작아야 합니다.
import Foundation
var str = "Swift"
func intStr(str: String) {
guard let intFromStr = Int(str) else {
print("값 변환에 실패하였습니다")
return
}
print("값이 변환되었습니다. 변환된 값은 \(intFromStr)입니다.")
}
intStr(str: str) // 값 변환에 실패하였습니다
if let으로 옵셔널 바인딩 처리
var str = "Swift"
if let intFromStr = Int(str) {
print("값이 변환되었습니다. 변환된 값은 \(intFromStr)입니다.")
} else {
print("값 변환에 실패하였습니다")
}
// 값 변환에 실패하였습니다
출처
꼼꼼한 재은씨의 Swift: 문법편
class/struct/enum 객체명 {
var 프로퍼티명: 타입 {
get {
필요한 연산 과정
return 반환값
}
set(매개변수명) {
필요한 연산구문
}
}
}
연산 프로퍼티는 다른 프로퍼티에 의존적이거나, 혹은 특정 연산을 통해 얻을 수 있는 값을 정의할 때 사용됨
e.g. 개인 정보 중 - 나이
나이는 출생 연도에 의존적이며, 현재 연도를 기준으로 계산해야 하므로 매년 그 값이 달라짐
import Foundation
struct UserInfo {
// 저장 프로퍼티: 태어난 연도
var birth: Int!
// 연산 프로퍼티: 올해가 몇년도인지 계산
var thisYear: Int! {
get {
let df = DateFormatter()
df.dateFormat = "yyyy"
return Int(df.string(from: Date()))
}
// 연산 프로퍼티: (올해 - 태어난 연도) + 1
var age: Int {
get {
return (self.thisYear - self.birth) + 1
}
}
}
}
let info = UserInfo(birth: 1980)
print(info.age)
꼼꼼한 재은씨 예제 그대로 따라친건데 안됨 🤔
Error message
There are four ways to handle errors in Swift.
You can propagate the error from a function to the code that calls that function
handle the error using a do-catch statement
handle the error as an optional value
assert that the error will not occur.
Propagating Errors Using Throwing Functions
import Foundation
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
struct Item {
var price: Int
var count: Int
}
class VendingMachine {
var inventory = [
"Candy Bar": Item(price: 12, count: 7),
"Chips": Item(price: 10, count: 4),
"Pretzels": Item(price: 7, count: 11)
]
var coinsDeposited = 0
func vend(itemNamed name: String) throws {
guard let item = inventory[name] else {
throw VendingMachineError.invalidSelection
}
guard item.count > 0 else {
throw VendingMachineError.outOfStock
}
guard item.price <= coinsDeposited else {
throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited)
}
coinsDeposited -= item.price
var newItem = item
newItem.count -= 1
inventory[name] = newItem
print("Dispensing \(name)")
}
}
let favoriteSnacks = [
"Alice": "Chips",
"Bob": "Licorice",
"Eve": "Pretzels",
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
try vendingMachine.vend(itemNamed: snackName)
}
struct PurchasedSnack {
let name: String
init(name: String, vendingMachine: VendingMachine) throws {
try vendingMachine.vend(itemNamed: name)
self.name = name
}
}
Handling Errors Using Do-Catch
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
print("Success! Yum.")
} catch VendingMachineError.invalidSelection {
print("Invalid Selection.")
} catch VendingMachineError.outOfStock {
print("Out of Stock.")
} catch VendingMachineError.insufficientFunds(let coninsNeeded) {
print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
} catch {
print("Unexpected error: \(error).")
}