source control을 통해 버전 관리 실행
프로젝트 생성 시 깃 연결을 해주거나, 추후에 source control을 통해 연결 가능하다.
repo, admin:public key, user, write:discussion 이 4개는 꼭 체크해줘야 한다.
브랜치 생성, 브랜치 전환 등 다양한 작업을 실행할 수 있다.
커밋 이력을 확인할 수 있으며 클릭 시, 특정 커밋 시점으로 돌아갈 수 있다.

원격 환경과 연결하기
Optional 타입으로 선언된 프로퍼티에 대해서 값이 있는지 없는지를 판별하기 위함
값의 유무에 대한 확신의 정도에 따라 4가지 정도 방식이 존재

강제 언래핑
var optional:String?
optional!
if let 바인딩
//if let 바인딩
//주의할 점은 optioanl값은 if조건절 내부에서만 사용가능하다.
var optional:String?
if let optional = optional {
print(optional)
} else {
print("nil")
}
//swift 5.7에서 새로 도입된 문법
if let optional {
print(optional)
} else {
print("nil")
}
//guard let 바인딩
//early exit 장점,
func guardletBinding() {
guard let optioanl = optional else {
print("nil")
}
print(optioanl)
}
nil coalescing
//nil 값에 대비해서 기본값을 세팅하는 것
var optional:String?
print(optional ?? "기본 값" )
isHidden 속성 활용하기@IBAction func testSecondTapGesture(_ sender: UITapGestureRecognizer) {
firstImageView.isHidden = firstImageView.isHidden == true ? false : true
}
//삼항 연산자 -> 프로퍼티 = 조건 ? 조건 성립: 조건 미성립
//스택 뷰의 경우 프로퍼티가 사라지면 남아있는 UI에 대해서 다시 레이아웃을 잡기 때문에,
//특정 UI컴포넌트가 일시적으로 사라지도록 할 때 유용하다. //1. 값 할당
firstImageView.isHidden == true
//2. 조건문 활용
if firstImageView.isHidden == true {
firstImageView.isHidden = false
} else {
firstImageView.isHidden = true
}
//3. not연산자 활용
firstImageView.isHidden = !firstImageView.isHidden
//4. 토글 메서드를 활용
firstImageView.isHidden.toggle()
//5. 삼함연산자
firstImageView.isHidden = firstImageView.isHidden == true ? false : true컴포넌트의 tag 활용
@IBAction func playButtonClicked(_ sender: UIButton) {
let list = ["가사1", "가사2", "가사3"]
//코드로 태그 지정
thirdButton.tag = 3
//태그값으로 가사 배열의 데이터 매칭
print(list[sender.tag - 1])
//텍스트 뷰는 스크롤 기능을 자동으로 탑재
textView.text = list[sender.tag - 1]
}
텍스트 뷰의 다양한 기능

매서드에서 반환값이 있는 것과 없는 것의 차이
//스트링의 append
var string:String = "안녕하세요"
func appending<T>(_ aString: T) -> String where T : StringProtocol
//반환값 있는 것 원본 배열에 영향을 주지 않는다.
string.appending("옹")
print(string)
mutating func append(_ other: String)
//반환값 없는 것 원본 배열에 영향을 준다.
string.append("옹")
print(string)
오픈소스를 사용하는 방식은 4가지가 존재하나, 가장 많이 사용하는 방식은 코코아팟과 SPM을 활용하는 방식
→ swift + github + 라이브러리가 필요한 요소 양식으로 구글링하면 해당하는 요소의 오픈소스가 검색된다.
오픈소스를 판단하는 기준
메이저/마이너/패치 순서로 표기한다.



index를 가지고 있다index에 따른 로직을 분기처리할 수 있다.
![]navigationVC를 활용한 방식과 present 메서드를 활용하는 방식을 사용한다.rootVC 를 주의해야 한다.fullscreen, current conetext의 경우 뒤로 가기 버튼을 통해 화면은 unwind해줘야 한다.fullscreen 은 전환할 화면은 전체 scene의 최상단에 위치시킨다.current conetext는 현재 VC의 scene에 최상단에 위치시킨다.page sheet, automatic는 버전의 차이 같은 기능

viewIsAppearing추가될 예정.viewDidLoad 메서드를 실행한다는 점 유의//기본 선언
enum Week {
case mon
case tuse
.
.
.
}
//원시값의 타입 선언
//정수형의 경우 따로 원시값을 할당하지 않아도
//순차적으로 0부터 할당 된다.
enum Week:Int {
case mon
case tuse
.
.
.
}
//원시값의 타입 선언2
enum Week:String {
case mon
case tuse
.
.
.
}
//원시값의 할당
enum Week:String {
case mon = "월"
case tuse = "화"
.
.
.
}
//CaseIterable 프로토콜 채택
//열겨형의 멤버를 배열처럼 사용할 수 있음.
enum Week:String, CaseIterable {
case mon = "월"
case tuse = "화"
.
.
.
}
print(Week.mon) // mon출력
print(Week.mon.rawValue)// '월'출력
let weekList = Week.allCases
//배열 처럼 사용할 수 있다.
print(weekList.count)
for item in 1...weekList.count {
print(...)
}
for item in weekList {
print(item.rawValue)
}영구적인 data 저장이 필요할 수 있다. 영구적인 저장을 위한 방식 중 사용자 로컬 기기에 데이터를 저장하는 방식이 userdefaults이다.
하나의 앱에 대해 하나의 저장소(사물함)를 배정받는다.
이때, 저장소는 지정된 것이 아니라 앱의 저장소(전체 사물함) 상황에 따라 유동적으로 변동된다.
→ Sand Box System
앱 샌드박스는 사용 권한을 통해 요청된 리소스에 대한 앱의 액세스를 제한함으로써 시스템 리소스 및 사용자 데이터에 대한 보호를 제공합니다.
*출처: [애플 공식 문서]
*참고자료:[iOS] iOS SandBox 란?
// 코드 흐름: 데이터 저장 -> key를 통해 value 추출 -> 용도에 맞게 사용
// 과제에서 피드백 사항 -> UserDefaults.standard과 같이 반복되는 리터럴은
// 상수로 선언 후 public하게 사용
let setUserDefaults = UserDefaults.standard
setUserDefaults.setValue(2023, forKey: "year")
setUserDefaults.setValue(7, forKey: "month")
let year = setUserDefaults.integer(forKey: "year")
let month = setUserDefaults.integer(forKey: "month")
print("\(year)년 \(month)월")
리터럴 할당optional타입으로 선언생성자 사용 //멤버와이즈 이니셜라이저 구문 제공 -> init() 메서드 자동으로 지원
struct BabyMonsterStruct {
var exp:Int
var name:String
var speed:Int
var power:Int
}

3. override
부모클래스로부터 물려받은 요소를 자식 클래스에서 사용할 때, 자식 클래스만의 기능으로 변경해서 사용할 수 있고 이를 override라고 함.
4. 참조 타입
→ 추후에 자세하게 설명
5. 애매한 용어
→ 최초에서 아무것도 상속 받지 않는 클래스를 BaseClass라고 한다. super/sub는 상대적인 개념이다.
viewWillDisappear 정도에 처리할 수 있다.viewWillAppear 시점에 대응tableView이다. tableView 에는 header와 footer가 따로 존재하다.plain grouped insetgrouped가 존재한다. numberOfRowsInSection, cellForRowAt 메서드는 꼭 정의해줘야 한다. IndexPath를 활용하면 코드를 많이 간소화할 수 있다.IndexPath: 중첩 배열에서 특정 위치에 대한 경로를 함께 나타내는 인덱스 목록이며, collection 타입의 한 종류viewDidLoad에 tableview.rowHeight 를 통해 높이를 지정할 수 있다. tableView.reloadData() 실행하면 된다. 


Extension(확장)은 특정 타입의 객체에 공통적인 요소를 일괄적으로 적용하고 싶을 때 사용한다.
//backgound Color 적용
extension UIViewController {
func setBackgroundColor {
self.view.backgroundColor = .white
}
}
//실제 적용한 예시
override func viewDidLoad() {
super.viewDidLoad()
backgroundColor()
}
TableView의 content
테이블뷰의 키보드 처리

바운스 효과
테이블 뷰의 최상단, 최하단에 스크롤이 도달하면 더 이상 당겨지지 않는 에니메이션 효과
Dinamic prototypes으로 개발자가 직접 cell을 구성해 연결할 수 있다.
로직
identifier 라는 일종의 식별자를 가지며, 반드시 tableView와 cell을 identifier 를 통해 연결시켜줘야 한다. 타입을 변경하기 위한 방법
as 키워드를 통해 상위 타입으로 캐스팅한다. as?, as! 키워들 통해 하위 타입으로 캐스팅한다. 과제에 적용해볼 사항
프로퍼티에는 저장, 연산 2가지 속성이 존재하는데, 연산 속성은 추후 학습
클래스와 구조체의 구조적인 차이
→ 이러한 속성 때문에, 구조체 인스턴스는 최초에 초기화가 실행되고 프로퍼티에 할당한 값의 변경이 immutable하다. (mutating 키워드 주목)
지연 속성(lazy)
point : 사용할지도 모르는 데이터를 초기화 시점에 모두 메모리에 올려두는 것은 비효율적이다.
→ 그래서 말 그래도 저장을 지연시켜 프로퍼티에 접근 시 데이터를 저장하도록 함.
(변수나 상수 자체를 초기화하지 않는 다는 말은 아님)
타입 속성(static)
인스턴스를 사용하지 않아도 접근 가능한 속성
→ 주로 해당 객체에 속하는 고유값 등을 많이 선언
구조체의 멤버와이즈 이니셜라이저