Swift 시작하기 | iOS 개발 공식 언어 완벽 입문
이 글의 핵심
Swift 시작하기: iOS 개발 공식 언어 완벽 입문. Xcode 설치·Hello World.
첫 iOS 앱 만들면서, 나는 “문법 책”보다 “왜 이 화면에 빨간 줄이 떴지?” 쪽이 훨씬 먼저 찾아왔어. Xcode 열고 템플릿 고른 다음, print 한 줄 넣고 시뮬 돌리면 콘솔에 뭔가 뜨잖아. 그 순간이 사실 가장 기쁜데, 그다음엔 Optional이랑 guard가 슬슬 끼어들기 시작해. 겁먹을 필요는 없고, 그냥 “앱이 돌아가게 만드는 데 꼭 필요한 안전장치”라고만 생각하면 돼. 시리즈 인덱스는 전체 목차 쪽에 있고, 비슷한 톤의 입문은 #01 “시작하기”도 있어. 다음 궁금하면 #02 변수와 타입로 이어가면 돼.
우선 재미(?) 없으면 끝나니까, 작동하는 걸 먼저 보자. 아래는 문자열로 연산자랑 숫자 둘을 던지면, 실패해도 콘솔에 “왜”가 보이게 만든 미니 계산기야. switch로 연산 쪼개고, 0으로 나누면 nil로 “망한 거”를 표현하는 패턴이야. 나중에 앱에서도 비슷하게 “없는 값 = nil, 있으면 풀고 쓴다” 루프로 계속 보게 돼.
import Foundation
func calculate(_ op: String, _ a: Double, _ b: Double) -> Double? {
switch op {
case "+": return a + b
case "-": return a - b
case "*": return a * b
case "/": return b == 0 ? nil : a / b
default: return nil
}
}
let cases: [(String, Double, Double)] = [
("+", 10, 5),
("/", 10, 0),
("^", 2, 3)
]
for (op, x, y) in cases {
if let r = calculate(op, x, y) {
print("\(x) \(op) \(y) = \(r)")
} else {
print("\(x) \(op) \(y) → 0으로 나눴거나, 아직 그 연산은 안 쓴다")
}
}
여기서 중요한 건 문법 나열이 아니라 감각이야. if let은 “optional에서 값 뽑힐 때만 안쪽으로 진입”이고, Double?은 “없을 수도 있다”는 걸 타입이 같이 들고 다니는 거지. C처럼 암시적으로 숫자가 섞이지 않는 것도, Swift가 초보를 살려주는 포인트야—덜 쓰고 싶다고 암씨 컴플레인하지 말고, 그냥 Double(i) 이런 식으로 의도를 써 주면 돼.
Hello World는 한 줄이면 끝이야. Playground에 넣고 돌리면 끝.
print("Hello, world!")
앱 타겟이면 구조가 달라지니까 (@main이나 main.swift 같은), 그때는 템플릿이 잡아주는 진입점을 건드리는 식이 되는데, 처음엔 Playground로 감 익혀도 충분해. 터미널에서 swift --version 찍을 수 있으면, 커맨드라인 툴 잡힌 거고, Xcode 쪽 Locations에서 command line tools가 뭘 가리키는지 한 번쯤만 확인해 두면 “왜 갑자기 다른 Swift가 돌지?” 싸움을 줄일 수 있어. Linux나 서버 쪽이면 Docker로 Swift 올리는 그림이 흔하고, iOS 앱이 목적이면 솔직히 맥 + Xcode 조합이 제일 말이 적어. Windows는 이 글 쓰는 시점 기준으로도 공식 루트가 자주 갈리니까, 그냥 “앱이 목적이면 맥” 정도로만 기억해 두고 최신 문서로 확인하는 걸 추천해.
변수랑 상수는 var / let 두 개로 끝이야. 기본은 let—나중에 바꿀 거 확실할 때만 var. 뇌절하려는 순간, “이 값 바뀌나?”만 물으면 절반이는 해결이라서.
var userName = "이몽룡"
userName = "성춘향"
let birthYear = 1990
// birthYear = 1991 // ㄴㄴ, let은 락
타입 추론은 “옆에 값이 있으면 컴파일러가 눈치챈다”는 거고, Int끼리랑 Double끼리 섞는 건 자동 캐스팅 안 해 주니까, 그냥 Double(i)나 Int(x)로 몸 풀어. 문자열 → 숫자는 Int("100")이 실패할 수 있어서 optional을 돌려—그게 바로 readLine() 받을 때 if let이 나오는 이유기도 해.
let message = "안녕하세요"
let count = 42
let price = 19.99
let isReady = true
var names: [String] = [] // 비어 있으면 타입 누가 앎
var scores: [String: Int] = [:]
Int / Double / String / Bool이 자주 쓰는 박스들이고, Bool은 다른 언어처럼 if 1 이런 거 안 돼. true / false로만 간다. 실수 끼리 Float 쓰는 경우는 GPU나 메모리 아낄 때 정도. 문자열은 \(뭐)로 박는 보간이 편해—print에 변수 때려 박는 일이 많거든. 여러 줄은 """ 감싸서 쓰면 돼.
컬렉션 티저만 갈기면, Array는 순서, Dictionary는 키-값, Set은 중복 싫어하고 멤버십 빠를 때. 나중에 컬렉션에서 COW 같은 얘기 나오는데, 지금은 “일단 for 돌릴 수 있나”만 봐도 OK야.
var nums = [1, 2, 3]
nums.append(4)
var capitals: [String: String] = [:]
capitals["KR"] = "Seoul"
var s: Set = [1, 2, 3]
s.insert(3) // 3은 한 번만
튜플은 임시로 묶을 때. 커지면 struct로 빼—그게 유지보수 쪽이 마음이 편해.
let http200 = (code: 200, message: "OK")
print(http200.code)
옵셔널은 진짜 중요해. “없을 수도 있어”를 ?로 박는 거. ?.는 앞이 nil이면 뒤는 안 봄, ??는 “nil이면 기본값”, if let / guard let은 “값 있을 때만 밑으로 진행”. !로 강제로 까는 건, 릴리즈 앱에선 눈돌리면 런타임 터지기 쉬우니… 예제/테스트 말곤 잘 안 써. 자세한 건 에러 처리·변수에서 이어갈게.
제어문은 if에 괄호 강제 없고, guard는 “이상하면 여기서 끊고 정상 루트는 밑으로” 느낌, switch는 fallthrough 기본이 아니고 패턴 맛이 좀 있어. for는 1...3이 닫힌 범위, 1..<3이 상한 빼는 거, while / repeat-while은 C랑 비슷한데 Bool만 받는 if가 있다는 점만 기억.
함수는 func, 반환이 짧은 식이면 return 생략되는 경우도 있고, 파라미터에 외부 라벨 붙이는 게 읽기 좋다는 쪽 팀이 많아. add(_ a: Int, _ b: Int) 처럼 언더스코어 쓰면 호출이 짧아지는 트레이드오프.
func greet(name: String) {
print("안녕, \(name)")
}
greet(name: "스위프트")
print랑 debugPrint는 콘솔 땜에, 민감 정보 휙휙 남기지 말기. readLine()은 import Foundation 하고, stdin 한 줄. GUI 앱에선 사실 콘솔이 아니라 텍스트필드·바인딩이 본처이지.
그래서 Swift가 뭐냐면, 2014년쯤 나와서 iOS/맥 앱 쪽 “그냥 이거”에 가깝고, 옛날엔 Obj-C랑 잘 엮이게 나왔지. Obj-C랑 C 프레임워크 아직 섞이니까, NS 같은 접두어 보이면 “아 옛 API구나” 정도. 타입은 안전하게 잡고, struct/enum 같은 값 타입 쓰라고 잔소리(?) 하는 편, 프로토콜로 능력만 묶는 스타일도 많고. Rust랑 똑같이 소유권 이런 건 아니고, 참조 쪽은 ARC, 값 쪽은 복사 쪽—모델이 달라.
객체 캐스팅은 as?가 안전, as!는 런타임 룰렛. 숫자끼리는 그냥 이니셜라이저로 밀어 넣는 게 정신건강에 이로워.
문자열 인덱스는 s[0] 안 되는 그거—String.Index 쓰는 설계라서 처음엔 짜증나. 잘릴 땐 Substring이 나올 수 있고, 오래 잡고 있지 말고 String(...)로 복사해 가져가. 이런 건 컬렉션이랑 겹쳐서, 막히면 그때 같이 봐.
암시적 옵셔널(String!)은 “처음엔 nil이어도, 나중엔 꼭 있다” 약속 같은 건데, 요즘은 if let 쪽 먼저 익힌 다음에 봐도 늦지 않아. #available은 “이 API iOS 15부터야” 같은 거 막는 울타리, 나중에 실기기/최소버전 잡을 때 봄직해.
SPM으로 CLI 조각 맛보고 싶으면 swift package init --type executable 해서 swift run—앱이 부담이면 이 루트가 짧고 좋아. CommandLine.arguments는 [0]이 실행 경로고 dropFirst()로 뒤에만 쓰는 식. 부록 10편은 여기엔 안 붙이고, 끼어들 포인트만: 서명(실기기)은 처음엔 시뮬레이터로만 문법 익혀도 됨, Playground 느리면 예제 잘라서 타겟으로 옮기기, xcode-select 꼬이면 “어느 Swift냐” 싸움남.
다음에 손댈 것—하루에 한 덩이만: 옵셔널로 같은 문제 if guard ?. ?? 네 갈래로 써보기, 문자열 앞뒤 잘라서 Substring이랑 String 느낁기, for-in으로만 돌다가 map으로 리팩터(다음날), 외부 라벨 있는 함수 3개 직접 짜서 읽기 테스트, String→Int 실패를 삼키는 입력 파서 짜기. 15분이면 readLine()으로 op랑 a b 받는 루프 + Double 실패면 다시, quit로 빠지게—위에 있던 calculate 그대로 갖다 써도 돼.
길게 정리: Swift는 “앱 돌릴 언어”로 손이 많이 가, let·옵셔널·switch만 몸에 붙으면 뒤로 갈수록 덜 기절해. 함수/클로저는 표현력 올리고, SwiftUI 쪽가면 콘솔 뇌를 UI/비동기 뇌로 갈아타야 하니까, 그때는 또 같이 욕하면서 읽자. 공식은 The Swift Programming Language랑 Swift.org 정도만 북마크해 두고, Evolution은 “언어가 왜 이렇게 됐지?” 볼 맛—비교 Kotlin은 다른 언어 감 잡을 때. 한 번에 다 못 읽겠으면, 제목만 보고 필요한 데만 뜯어 먹어도 돼.