2주차 정리

lyoodong·2023년 7월 24일

github

  • 연결

source control을 통해 버전 관리 실행

프로젝트 생성 시 깃 연결을 해주거나, 추후에 source control을 통해 연결 가능하다.

  • 토큰 생성

repo, admin:public key, user, write:discussion 이 4개는 꼭 체크해줘야 한다.

  • Source control navigator

브랜치 생성, 브랜치 전환 등 다양한 작업을 실행할 수 있다.

커밋 이력을 확인할 수 있으며 클릭 시, 특정 커밋 시점으로 돌아갈 수 있다.

원격 환경과 연결하기

Optional Binding

Optional 타입으로 선언된 프로퍼티에 대해서 값이 있는지 없는지를 판별하기 위함

  • 종류

값의 유무에 대한 확신의 정도에 따라 4가지 정도 방식이 존재

  1. 강제 언래핑

    var optional:String? 
    
    optional!
  2. 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)
    
    }
  3. nil coalescing

    //nil 값에 대비해서 기본값을 세팅하는 것
    var optional:String? 
    
    print(optional ?? "기본 값" )

실습

  • stackview에서 isHidden 속성 활용하기
    @IBAction func testSecondTapGesture(_ sender: UITapGestureRecognizer) {
            firstImageView.isHidden = firstImageView.isHidden == true ? false : true 
        }
    //삼항 연산자 -> 프로퍼티 = 조건 ? 조건 성립: 조건 미성립
    //스택 뷰의 경우 프로퍼티가 사라지면 남아있는 UI에 대해서 다시 레이아웃을 잡기 때문에,
    //특정 UI컴포넌트가 일시적으로 사라지도록 할 때 유용하다. 
  • 'Bool' 타입에서 값 변경하기
    //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 + 라이브러리가 필요한 요소 양식으로 구글링하면 해당하는 요소의 오픈소스가 검색된다.

  • 오픈소스를 판단하는 기준

  1. 깃허브 스타
  2. 업데이트 주기
    → 1년 이내이면 좋다. 업데이트 주기가 너무 긴 것은 버전 대응 등의 문제를 야기할 수 있다.
  • 버전을 표기하는 룰
    예시: 3.2.4 → 메이저/마이너/패치 순서로 표기한다.



세그먼트 Control

  • 세그먼트 control의 경우 각각의 버튼에 대해서 index를 가지고 있다
  • index에 따른 로직을 분기처리할 수 있다.
  • 세그먼트 이벤트에도 다양한 종류가 있다.

파일 경로 문제

  • 프로젝트 내부의 파일의 경로를 설정하는 방식이 여러가지가 존재한다.
  • 절대 경로로 설정한다면, 협업 시 내부 resource나 source의 파일 경로가 꼬일 수 있다.
  • 따라서 가능하면 상대 경로로(프로젝트 내부의 경로는 프로젝트 폴더가 위치한 경로와 무관하다) 설정해주는 것이 좋다.
    ![]

화면전환

  • 크게 navigationVC를 활용한 방식과 present 메서드를 활용하는 방식을 사용한다.
  • rootVC 를 주의해야 한다.
  • show, show detail, modal, modal fullscreen, modal current conetext등 다양한 방식이 존재하니 상황에 맞게 사용하면 된다.
  • fullscreen, current conetext의 경우 뒤로 가기 버튼을 통해 화면은 unwind해줘야 한다.
  • fullscreen 은 전환할 화면은 전체 scene의 최상단에 위치시킨다.
  • 반면, current conetext는 현재 VC의 scene에 최상단에 위치시킨다.
    → 따라서 탭바 등 상위 view는 화면전환을 해도 화면에 나타나게 된다.
  • page sheet, automatic는 버전의 차이 같은 기능

뷰컨트롤러의 생명주기

  • 5가지 메서드가 존재한다. *iOS 17부터 viewIsAppearing추가될 예정.
  • rootVC는 최초에 1회만 viewDidLoad 메서드를 실행한다는 점 유의

enum

  • 공통의 주제로 묶을 수 있는 데이터의 묶음
  • ‘열거형’이라는 키워드로 사용된다.
  • 각 멤버(case)는 원시값(rawValue)을 가질 수 있다.
    //기본 선언
    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)
    }

    UserDefualts

영구적인 data 저장이 필요할 수 있다. 영구적인 저장을 위한 방식 중 사용자 로컬 기기에 데이터를 저장하는 방식이 userdefaults이다.

  • 특징

하나의 앱에 대해 하나의 저장소(사물함)를 배정받는다.

이때, 저장소는 지정된 것이 아니라 앱의 저장소(전체 사물함) 상황에 따라 유동적으로 변동된다.

Sand Box System

💡 App Sandbox provides protection to system resources and user data by limiting your app’s access to resources requested through entitlements.

앱 샌드박스는 사용 권한을 통해 요청된 리소스에 대한 앱의 액세스를 제한함으로써 시스템 리소스 및 사용자 데이터에 대한 보호를 제공합니다.

*출처: [애플 공식 문서]

*참고자료:[iOS] iOS SandBox 란?

  • code
// 코드 흐름: 데이터 저장 -> 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)월")

클래스와 구조체

  • 객체의 공통적인 요소를 추상화해 만들어낸 하나의 ‘틀’
  • 특징
  1. 초기화
    1. 선언과 동시에 리터럴 할당
    2. optional타입으로 선언
    3. 생성자 사용
  2. 구조체의 맴버와이즈 이니셜라이저
    //멤버와이즈 이니셜라이저 구문 제공 -> init() 메서드 자동으로 지원
    struct BabyMonsterStruct {
        var exp:Int
        var name:String
        var speed:Int
        var power:Int
    }


3. override
부모클래스로부터 물려받은 요소를 자식 클래스에서 사용할 때, 자식 클래스만의 기능으로 변경해서 사용할 수 있고 이를 override라고 함.
4. 참조 타입
→ 추후에 자세하게 설명
5. 애매한 용어
→ 최초에서 아무것도 상속 받지 않는 클래스를 BaseClass라고 한다. super/sub는 상대적인 개념이다.

Emotion App 과제 이슈 및 피드백

  • 데이터 저장 시점
    → 사실 앱에 내장된 기능이라 성능 이슈를 크게 신경쓰지 않아도 된다.
    → 그래도 굳이 처리를 한다면 viewWillDisappear 정도에 처리할 수 있다.
    → 하지만, 이러한 경우 화면이 전환되지 않고 앱이 꺼진다면, 데이터가 유실된다.
  • 화면에서 데이터 갱신 시점
    viewWillAppear 시점에 대응
  • 화면 전환 시 데이터 전달(다음 주에 학습)

테이블뷰 컨트롤러

  • 기본 구조
  1. RootView가 tableView이다.
  2. tableView 에는 header와 footer가 따로 존재하다.
    → header는 서치바, footer는 사업자 정보 표기 등에 활용할 수 있다.
  3. 스타일에는 plain grouped insetgrouped가 존재한다.
  4. numberOfRowsInSection, cellForRowAt 메서드는 꼭 정의해줘야 한다.
  5. cell에 데이터를 할당할 떼, 배열과 IndexPath를 활용하면 코드를 많이 간소화할 수 있다.
    IndexPath: 중첩 배열에서 특정 위치에 대한 경로를 함께 나타내는 인덱스 목록이며, collection 타입의 한 종류
  6. cell의 높이가 고정된 경우 viewDidLoadtableview.rowHeight 를 통해 높이를 지정할 수 있다.
  7. 특정 시점에서 테이블 뷰의 데이터를 갱신하고 싶다면, tableView.reloadData() 실행하면 된다.



Extension

  • 개념

Extension(확장)은 특정 타입의 객체에 공통적인 요소를 일괄적으로 적용하고 싶을 때 사용한다.

//backgound Color 적용
extension UIViewController {
	func setBackgroundColor {
		self.view.backgroundColor = .white
	}
}

//실제 적용한 예시
override func viewDidLoad() {
	super.viewDidLoad()
	backgroundColor()
}

복습

TableView의 content

  1. Dinamic prototypes
  2. Static cells → 코드 없이 스토리보드 상에서 구성한다는 것이 포인트

테이블뷰의 키보드 처리

  • 스크롤 시 키보드 내린다. (storyboard의 attribute inspector 영역에서 체크할 수 있다.)

바운스 효과

테이블 뷰의 최상단, 최하단에 스크롤이 도달하면 더 이상 당겨지지 않는 에니메이션 효과

Custom Cell

Dinamic prototypes으로 개발자가 직접 cell을 구성해 연결할 수 있다.

로직

  1. scene 제작
  2. logic을 작성할 tableview, cell 파일 생성
  3. 각각 scene과 연결
    이때, cell은 identifier 라는 일종의 식별자를 가지며, 반드시 tableView와 cell을 identifier 를 통해 연결시켜줘야 한다.

타입 캐스팅

타입을 변경하기 위한 방법

  1. 업 캐스팅: as 키워드를 통해 상위 타입으로 캐스팅한다.
  2. 다운 캐스팅: as?, as! 키워들 통해 하위 타입으로 캐스팅한다.

과제에 적용해볼 사항

  • 상수 바인딩을 통해 반복되는 코드 최소화
  • 셀 신과 로직 연결(cell identifier 연결 및 cell 타입 캐스팅)
  • cell 수정 코드 함수화 후 cell 파일로 이동
  • 구조체 형식으로 데이터를 VC와 분리시킨다.

클래스와 구조체의 프로퍼티

프로퍼티에는 저장, 연산 2가지 속성이 존재하는데, 연산 속성은 추후 학습

클래스와 구조체의 구조적인 차이

  1. class는 참조 타입, struct는 값 타입이다.
  • class는 인스턴스를 생성하면 힙 영역에 저장되고, 해당 인스턴스를 가리키는 참조가 생성된다.
  • 반면, struct는 인스턴스가 변수나 상수에 할당되면 스택에 저장된다. 즉, 변수나 상수가 직접 값을 보유하게 된다.

→ 이러한 속성 때문에, 구조체 인스턴스는 최초에 초기화가 실행되고 프로퍼티에 할당한 값의 변경이 immutable하다. (mutating 키워드 주목)

지연 속성(lazy)

point : 사용할지도 모르는 데이터를 초기화 시점에 모두 메모리에 올려두는 것은 비효율적이다.

→ 그래서 말 그래도 저장을 지연시켜 프로퍼티에 접근 시 데이터를 저장하도록 함.
(변수나 상수 자체를 초기화하지 않는 다는 말은 아님)

타입 속성(static)

인스턴스를 사용하지 않아도 접근 가능한 속성

→ 주로 해당 객체에 속하는 고유값 등을 많이 선언

  • 구조체의 멤버와이즈 이니셜라이저

0개의 댓글