개발/swift

[swift] swift 언어 정리 (1) - 개념 & 문법

iris3455 2025. 3. 13. 23:52

기원

2014 : WWDC에서 Objective C를 대체하는 swift 등장

2019 : swift UI 디자인 프레임워크 등장

 

 

특징

  • 세미콜론이 없음
  • 타입 안정성 
    ex) var name : String (타입을 지정해줌)
  • 메모리 관리를 자동으로 해줌 (ARC - Automatic Reference Counting)
  • 함수형 프로그래밍 언어 (고차 함수 , 클로져)
  • xcode에서 플레이 그라운드 지원
  • LiveView 사용 가능

 

실시간 UI/UX 확인

1. Playground에서 Live View 사용

import PlaygroundSupport 

PlaygroundPage.current.setLiveView(content)​

 

장점

 

빠른 실험 가능

  • 코드 실행 후 바로 결과 확인 (SwiftUI 프로젝트가 아니어도 UI 테스트 가능).
  • UIKit, SwiftUI, SceneKit, SpriteKit 등 다양한 프레임워크 테스트 가능.

UIKit에서도 사용 가능

  • SwiftUI 프로젝트가 아니어도 UIViewController, NSViewController 등을 테스트 가능.
  • import PlaygroundSupport로 UIKit 기반 UI를 간단히 띄울 수 있음.

애니메이션 및 인터랙션 테스트 가능

  • liveView를 활용하면 SwiftUI 또는 UIKit에서의 애니메이션 동작을 실시간 확인 가능.

단점

 

완전한 앱 환경이 아님

  • AppDelegate나 SceneDelegate가 없기 때문에 앱 수준에서 테스트하기 어려움.
  • 네트워크 요청, CoreData 등은 따로 처리해야 함.

기능이 제한적

  • SwiftUI의 @State, @Binding 등과 같은 상태 변화를 Playground에서 100% 활용하기 어려움.
  • onAppear() 등의 일부 SwiftUI 기능이 기대대로 동작하지 않을 수 있음.

실제 기기 미리보기 불가

  • macOS에서만 Playground 실행 가능하며, iOS 기기에서 테스트할 수 없음.

 


2. SwiftUI Preview 사용 (Swift 프로젝트에서 활용)

import SwiftUI


#Preview {
  ContentView()
}

 

장점

 

SwiftUI 기반 UI 미리보기 최적화

  • Xcode의 미리보기 캔버스에서 즉시 확인 가능.
  • 여러 개의 뷰를 동시에 비교 가능.

앱 환경과 더 가깝게 테스트 가능

  • SwiftUI의 @State, @Binding, onAppear() 등이 정상적으로 동작.
  • iOS/macOS/watchOS/tvOS 환경을 직접 설정 가능.

다양한 기기 및 다크 모드 지원

  • PreviewDevice("iPhone 15 Pro") 등으로 기기별 화면 확인 가능.
  • 다크 모드, 언어 설정 변경, 다양한 화면 크기에서 테스트 가능.

실제 프로젝트에서 바로 활용 가능

  • SwiftUI 코드가 직접 실행되므로, Playground보다 프로젝트 내에서 더 실용적임.
  • #Preview {} 또는 @PreviewProvider 사용으로 Playground 없이도 빠르게 UI 확인 가능.

단점

 

UIKit은 미리보기 지원 X

  • SwiftUI 프로젝트가 아닌 경우 UIViewController 기반 UI 미리보기가 어렵거나 불가능함.
  • UIKit을 사용하려면 UIHostingController 등을 사용해야 함.

일부 동적 기능 테스트 어려움

  • API 호출, CoreData, 파일 시스템 액세스 등의 테스트가 제한적.
  • 터치 제스처, 애니메이션 테스트는 제한적이거나 느릴 수 있음.

 

 

조건문

1. guard 문

  • guard는 코드의 가독성을 높이고, 조기에 오류 처리를 할 수 있도록 도와주는 조건문
  • 조건이 false일 경우, 반드시 return, throw, break, continue 중 하나를 사용해 실행을 중단해야 함
  • Swift에서 "조기 탈출(Early Exit)" 패턴을 구현하는 데 유용함
func greet(person: String?){
// nil 일 경우
	guard let name = person else {
		print("No name provided")
		return
	}
// Value 값 존재할 경우
}

 

 

2. switch-case

  • break 필요 없음
  • 해당 조건 만족하더라도 fallthrough를 사용시 break 없는 것처럼 케이스 진행
switch number {
	case 1:
    	fallthrough
    case 2:
    	fallthrough
    case 3:
    	fallthrough
    defalut:
    	// fallthrough을 사용했으므로 default 항상 실행
}

 

 

3. for

// index가 필요하지 않을때 
for _ in 1...5{
	print("hello")
}

// index 없이 값 바로 출력 가능
let number = [1,2,3,4,5]
for num in number{
	print(num)
}

// 딕셔너리 사용 (타입 추론 안됨 -> 타입 안정성 체크)
let dic: [String:Any] = ["name":"iris", "age":25, "gender":"F"]
for (key, value) in dic {
	print("\(key) : \(value)")
}

//for each
let numbers = [1,2,3,4,5]

ForEach (numbers ,id: ./self) number in {
	Text("\(number)") // 출력 1,2,3,4,5
}

 

 

4. while

while condition{
// condition 만족하면 실행
}

repeat {
// 처음 한번은 무조건 실행 
// condition 에 따라 나오거나 계속 실행
} while condition

 

 

Collection

 

1. 배열

  • 형태
// 빈 배열 생성
var emptyArray = [String]()
var emptyArray: [String] = []

// 데이터 있는 배열 생성
var arrayWithData1 = [String](Array(repeating: "ex", count: 3))
var arrayWithData2 = [String](Array(repeating : "basic", count:3))

var sumArray = arrayWithData1 + arrayWithData2
print(sumArray) // ["ex","ex","ex","basic","basic","basic"]
  • 사용
var array: [Int] =[ 1,5,3,6,3,8,90,14 ]

/// 1. 배열의 개수
let count = array.count // 8

/// 2. 배열 비어있는지 확인
let isEmpty = array.isEmpty // false

/// 3. 배열에 특정 인덱스에 접근하여 값 출력
let val = array[1] // 5

/// 4. 배열 정렬
// sort -> 직접적으로 배열에 접근하여 정렬
array.sort(by: {$0 < $1})
array.sort( < )

// sorted -> 배열을 복사하여 정렬하여 새로운 배열 반환
let newArray = array.sorted(by : {$0 < $1})
let newArray = array.sorted( < )

/// 5. 배열 항목 무작위로 섞기
// shuffle -> 직접적으로 배열에 접근하여 섞음
array.shuffle()

shuffled -> 배열을 복사하여 새로운 배열에 반환
var newArray = array.shuffled()

/// 6. 배열에 새로운 항목 추가
array.append(100) // [ 1,5,3,6,3,8,90,14,100 ]
array += [100] // [ 1,5,3,6,3,8,90,14,100 ]

/// 7. 특정 인덱스에 데이터를 추가
array.insert(999, at: 1) // [ 1,999,5,3,6,3,8,90,14,100 ]

/// 8. 인덱스로 배열 요소 삭제
array.remove(at: 2) // [ 1,5,6,3,8,90,14 ]

/// 9. 해당 값의 모든 배열 요소 삭제
array.removeAll(where: {(element: Int) -> Bool in 
	return element == 3
})
array.removeAll(where: {element in element == 3})
array.removeAll { $0 == 3 } // [ 1,5,6,8,90,14 ]

/// 10. 값이 배열에 있는경우 첫번째만 삭제
let index = array.firstIndex(of: 3) // 3을 값으로 가지는 배열의 첫번째 인덱스

if index {
	array.remove(at: index)
}
print(array) // [ 1,5,6,3,8,90,14 ]

/// 11. 배열 전체 삭제
array.removeAll()

 

 

2. 딕셔너리

  • 형태
var 딕셔너리이름: [키타입 : 벨류타입] = [:]

// 빈 딕셔너리 생성
var fruitPrice = [String : Int]()
var fruitPrice: [String : Int] = [:]
  • 사용
var fruitPrice: [String:Int] = ["Grapes": 2, "Banana": 8]

/// 1. 개수
fruitPrice.count // 2


/// 2. 특정 키에 해당하는 밸류값 접근하기
fruitPrice["Grapes"] // 2


/// 3. 새로운 항목 추가하기
fruitPrice["Stone"] = 9 // ["Stone": 9, "Grapes": 2, "Banana": 8] -> 배열과 달리 순서가 중요하지 않음


/// 4. 딕셔너리 항목 출력하기
for (key, value) in fruitPrice {
	print("\(key) and \(value)") // Stone and 9 ...
}

/// 5. 특정 키 , 값 삭제
let deletedDicValue = fruitPrice.removeValue(forKey: "Grapes") // fruitPrice = ["Banana": 8]
print(deletedDic) // 2

fruitPrice["Grapes"] = nil // 반환값 없음
print(fruitPrice) // ["Banana": 8]

 

 

2. set

  • 형태
// 비어있는 set [] 생성
var basicSet = Set<Int>()
var basicSet : Set<Int> = []
  • 사용
var testSet: Set<Int> = [3,4,4,4,5,5,5,1,1,3,3]

/// 1. 새로운 항목 추가하기
testSet.insert(32) // [1,3,4,5,32] -> 마찬가지로 순서 상관없음


/// 2. 특정 항목이 포함되어있는지
testSet.contains(33) // false

/// 3. 특정 항목 제거하기
testSet.remove(3) // [1,4,5]

/// 4. 항목들 출력하기
for val in testSet{
	print(val) // 1 3 4 5
}