TIL

33일차 TIL

h_luz 2024. 4. 12. 22:16

 

Swift 알고리즘 및 언어공부

 

57. 모의고사완전탐색 _ 프로그래머스

 

우선 배열이 숫자가 반복되고 있는데, 어떻게 0으로 돌아가지? 에 대한 고민을 많이 했던 것 같다!

근데 전에 날짜 요일 구하는 알고리즘에서 %7 해줬던 게 생각나서 어찌어찌하다 보니 이렇게 코드를 짰다.

import Foundation

func solution(_ answers:[Int]) -> [Int] {
    let oneP:[Int] = [1,2,3,4,5]
    let twoP:[Int] = [2,1,2,3,2,4,2,5]
    let threeP:[Int] = [3,3,1,1,2,2,4,4,5,5]

    var correct1:Int = 0 // 1 맞힌 문제
    var correct2:Int = 0 // 2 맞힌 문제
    var correct3:Int = 0 // 3 맞힌 문제
    var result:[Int] = [] //결과 배열

    for i in 0..<answers.count {
        if oneP[i%oneP.count] == answers[i] {
            correct1 += 1
        }
        if twoP[i%twoP.count] == answers[i] {
            correct2 += 1
        }
        if threeP[i%threeP.count] == answers[i] {
            correct3 += 1
        }
    }

    let maxCorrect = max(correct1, correct2, correct3)

    if correct1 == maxCorrect { result.append(1) }
    if correct2 == maxCorrect { result.append(2) }
    if correct3 == maxCorrect { result.append(3) }

    return result.sorted()
}

뭔가 완성하고 보니 간단하고, 단순해 보이지만 정말 쉽지 않다ㅜㅜ  

풀렸을 때는 오 됐다 하고 뿌듯하지만, 이렇게 하는 거 맞는 거 같은데 오류 나서 틀렸다 할 때는 진짜,,

그냥 시작하는 것보다 어려움.. ㅠㅜㅠ

 

나만 그런 거 아니겠지.. ㅠㅠ 다들 화이ㅣㅇ팅...

 


 

강의정리 (스파르타 코딩클럽)

 

그럼 어제 듣던 강의를 마저 들어보자

 

(중요!)

4. Core Data

: 데이터를 관리하고, 영구적으로 저장하는 데 사용되는 프레임 워크( 별도 외부 라이브러리를 사용하지 않는 경우 Core Data를 주로 사용)

    ㄴ 데이터 모델을 정의하고, 이를 기반으로 데이터를 읽고 쓸 수 있음

 

사용 방법

‣ Core Data를 사용하기 위한 Data Model 생성

    ㄴ 1 처음 프로젝트 생성 시, Core Data 체크 옵션 선택

    ㄴ 2 체크하지 않았을 경우, command + n 단축키

        ㄴ 화면에 Core Data에 Data Model 선택

‣ Core Data Stack 설정

    ㄴ AppDelegate.swift 에 설정해 준다

    ㄴ import CoreData 필수 선언!

//AppDelegate.swift
// 맨 위에 import CoreData

//class AppDelegte 안에 코드 적어주기

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name:/*생성한 Data Model명*/)
    // 영구 저장소 불러오기
    container.loadPersistentStores ( completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

// CoreData 현재 상태 저장 메소드 (앱 종료 시 변경사항 저장 등,,)
func saveContext() {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

 

Core Data Stack

: 데이터를 관리하고 저장하기 위한 Core Data 프레임 워크의 핵심 구성요소들의 집합

  • Persistent container (NSPersistentContainer)
    • Model (NSManagedObjectModel)
      : 데이터 모델을 정의하는 객체, Entity와 그들의 속성을 정의 (데이터 베이스 스키마)
    • Context (NSManagedObjectContext)
      : 데이터를 가져오거나 수정하는 객체 (메모리에서 데이터 관리, 데이터 베이스와 상호작용)
    • Store coordinator (NSPersistentStoreCoordinator)
      : 영구 저장소 연결 관리, 데이터베이스와의 통신 관리

* NS 타입 (참고)

    ㄴ NS가 붙은 타입은 NSString, NSArray, NSSet, NSDictionary 등등 여러 가지가 있다.

    ㄴ NextStep의 줄임말로, 예전 Objective-C 시절의 타입

    ㄴ 필요시 Swift의 타입들을 이들 타입으로 브릿징 하여 사용할 수 있다.(String → NSString)


데이터 모델링

Data Model 구성요소

‣  Entity : 데이터베이스의 테이블

    ㄴ 데이터 모델 내에서 객체의 유형을 정의, 객체의 속성을 나타냄

왼쪽 하단에 Add Entity

Entity 주요 속성

- Entity Name : 엔티티 이름

- Abstract Entity : 추상 Entity로 만들 경우, 해당 옵션 선택

- Parent Entity : Child Entity가 해당 속성을 상속하도록 할 수 있다 (기본적으로 비어있는 필드)

- Class Name : Entity 인스턴스를 만들 때 사용할 class Name (Entity의 이름 미러링)

- Module : Entity class가 있는 모듈

 

‣ Attribute : 데이터베이스의 column 혹은 attribute

    ㄴ Entity가 가지는 속성들을 나타냄

우측 하단에 Add Attribute나 + 버튼으로 추가 가능

Attribute 주요 속성

- Attribute Type : UIPickerView의 데이터를 제공하는 객체 설정

- Optional : 필수 속성 선택 가능

- Validation : 유효성 검사 옵션 지정

- Default Value : 데이터 생성 시점에 기본값 지정 가능

 

‣ Relationship : 두 개 이상의 Entity를 정의한 후 서로 간의 관계를 추가할 수 있다.

Pet과 Person Relationship 추가

Relationship 주요 속성

- Optinoal : 필수 속성 선택 가능

- Destination : 관계를 설정할 대상이 되는 Entity 선택

- Delete Rule : 원본 인스턴스를 삭제할 때 변경 내용이 Relationship 간에 전파되는 방식 지정

    ㄴ No Action : 원본은 삭제하지만 수동으로 업데이트하는 모든 객체에 대해 참조를 남김

    ㄴ Nullify : destination의 참조를 nil로 설정

    ㄴ Cascade : destination 객체를 연쇄적으로 삭제

    ㄴ Deny : 아무 destination이 없는 경우에만 원본 삭제

- Type : Relationship을 1:1(to one) 인지 1:N(to many) 인지와 같은 것들을 선택


Core Data 직접 코드에 사용하기

 

모델 Entity 객체 설정

 

 

AppDelegate에 설정한 persistentContainer에 접근

 

 

Data 생성

func saveData() {
    guard let context = self.persistentContainer?.viewContext else { return }
     
    let newCar = Car(context: context)
        
    newCar.id = UUID()
    newCar.name = "benz"
        
    try? context.save()
}

 

 

Data 읽기

//데이터 읽기
func getData() {
    guard let context = self.persistentContainer?.viewContext else { return }
        
    let request = Car.fetchRequest()
    let cars = try? context.fetch(request)
        
    print(cars)
}

viewDidLoad에 함수를 실행해주면 데이터가 저장되어서 읽히는 것을 볼 수 있음

 

 

Data 수정(업데이트)

//데이터 업데이트(수정)
func updateData() {
    guard let context = self.persistentContainer?.viewContext else { return }
        
    let request = Car.fetchRequest()
    guard let cars = try? context.fetch(request) else { return }
        
    let filteredCars = cars.filter{ $0.name == "benz" }
        
    for car in filteredCars {
        car.name = "tesla"
    }
    try? context.save()
}

benz -> tesla 로 변경됨

 

 

Data 삭제

//데이터 삭제(Delete)
func deleteData() {
    guard let context = self.persistentContainer?.viewContext else { return }
        
    let request = Car.fetchRequest()
    guard let cars = try? context.fetch(request) else { return }
        
    let filteredCars = cars.filter{ $0.name == "tesla" }
    for car in filteredCars {
        context.delete(car)
    }
    try? context.save()
}

삭제되어 Optional([])이 뜬다

 


화면전환

1. Present

    - Modal interface(화면이 아래에서 위로 올라

오는 형식) 구현에 주로 사용됨

        ㄴ Modal PresentationStyle

            ㄴ automatic : 시스템에서 선택한 기본 프레젠테이션 스타일

            ㄴ fullScreen : 전체 화면을 덮는 프레젠테이션 스타일

            ㄴ pageSheet : 기본 콘텐츠를 부분적으로 포함하는 프레젠테이션 스타일

            ㄴ formSheet : 화면 가운데에 콘텐츠를 표시하는 프레젠테이션 스타일

2. Push

    - Animation을 사용해서 새로운 ViewController가 Push 된다. (이전 화면은 숨김)

    - 계층 구조를 가지게 됨

 

Action Segue 사용하여 화면 전환

1. Present (modal)

- Present 버튼에서 control을 누른 상태로 다른 View Controller에 드래그해 주면 Action Segue로 화면끼리 연결 가능

- show 선택 시 이렇게 연결이 되어있는 것을 볼 수 있다.

- 실행해 보면, 버튼 클릭 시 모달이 올라온다

 

2. Push (Navigation Controller)

처음 화면이 될 View Controller를 선택해서 우측 하단에 Navigation Controller를 선택해 줄 수 있다.

이렇게 Navigation Controller를 선택해 주면 modal 형식이 아닌 계층 형식으로 화면전환이 된다.

실행시키면 이런 식으로 화면이 뜨는 것을 볼 수 있음

 

Manual Segue 사용하여 화면 전환

: Action Segue와 다른 점은 필요에 따라 코드로 연결 (즉, 트리거 방식이 다름)

View Controller 맨 왼쪽에 있는 노란 버튼(?)을 control을 누른 채로 다음 화면에 드래그해서 Menual Segue에 Show로 연결해준다

 

Identifier 설정하기

코드로 버튼 연결해서 화면이 전환되도록 한다.

 

Code를 사용하여 화면 전환

Storyboard ID 설정

코드에서 설정 (Present)

코드에서 설정 (Push)

* Push를 위해서는 Navigation Controller 를 추가해야함 !

 

Unwind Segue로 이전 화면으로 돌아가기

이전 화면으로 돌아가게 해 줄 버튼 생성

먼저 unwindToFirst 액션 세그를 만들어준다.

그리고 돌아가기 버튼을 control 누른 채로 드래그해서 Exit에 갖다대면 이렇게 만들어준 unwindToFirst가 뜬다.

이걸 연결해주고 실행해보면 돌아가기 버튼을 누르면 이전 화면으로 돌아가는 것을 볼 수 있다

 


 

이제 과제 시작 ~ ^^

'TIL' 카테고리의 다른 글

35일차 TIL  (8) 2024.04.16
34일차 TIL  (4) 2024.04.15
32일차 TIL  (4) 2024.04.11
31일차 TIL  (8) 2024.04.09
30일차 TIL  (1) 2024.04.08