ToDo
✅ 조금은 부지런해진 나
✅ 감사해 🙏

 

매일 나태해 지는 나를 어떡하면 조금 부지런하게 살아갈수 있을지를 고민하던중

공부하는 환경을 바꾸기로 했습니다..하하 

바로 스터디 카페에 출첵을 하는것이죠!

이제 시간도 정해서 매일 오는 것으로 합시다 하하.하..ㅎ..ㅇ..

 

배운점

강의를 들으며 AppDelegate에 있는 코드를 뜯어보고있었습니다.
눈에 안들어오는 document까지,,

//SQLite DB
lazy var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "DataModel")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {

            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

// MARK: - Core Data Saving support

func saveContext () {
    //context는 git의 스테이징area와 바슷
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {

            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

 

 

1. persistentContainer 변수.

- NSPersistentContainer는 데이터 모델과 저장소를 관리합니다.

- lazy var로 선언되며 처음 접근할때만 초기화됩니다.

- loadPersistentStores를 호출하여 데이터모델을 로드하고 영구 저장소를 설정합니다.

 

2. saveContext 함수

- saveContext함수는 데이터 변경을 저장소에 반영하는 역할을 합니다.

- viewContext는 github의 스테이징 영역과 유사한 개념으로 데이터를 변경하고 업데이트 할 수 있는 영역이다.

- context.hasChanges를 통해 현제 컨텍스트에 변경 사항이 있는지 확인하고, 변경사항이 있을경우

context.save()를 호출하여 저장소에 변경을 저장합니다.

 

 

 

CoreData CRUD

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

context를 AppDelegate의 persistentContainer로 부터 가져와서 사용한다.

 

- Create

let newItem = Item(context: self.context)
newItem.title = textField.text!
newItem.done = false
newItem.parentCategory = self.selectedCategory //Item과 Category의 정보저장
self.itemArray.append(newItem)

self.saveItems()

 

새로운 Item 객체를 생성합니다.

이 객체가 데이터에 할당된 후에 context.save()를 통해 CoreData에 저장됩니다.

 

-Read

    func loadItems(with request: NSFetchRequest<Item> = Item.fetchRequest(), predicate: NSPredicate? = nil) {
        do {
            itemArray = try context.fetch(request)
        } catch {
            print("Error fetching data from context \(error)")
        }
    }

loadItems메서드는 CoreData에서 데이터를 가져와 itemArray에 할당합니다.

NSPredicate를 통해 득정 조건에 따라 데이터를 필텉링합니다.

 

-Update

//MARK: - TableView Delegate Method
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    itemArray[indexPath.row].done = !itemArray[indexPath.row].done

    //DB에 저장
    saveItems()
}

func saveItems() {

    do {
        try context.save()
    } catch {
        print("Error saving context \(error)")
    }

    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
}

itemArray[indexPath.row].done = !itemArray[indexPath.row].done
으로 변경이 된다.

context.save()로 변경사항을 DB에 저장한다.

 

-Delete

//context delete부터 먼저 제거해야함!
context.delete(itemArray[indexPath.row])
itemArray.remove(at: indexPath.row)

삭제시에는 context.delete에 삭제될 객체를 넣어주어야 context에 삭제사항이 반영된다.

context에 삭제사항을 반영하고 객체를 삭제하는 순서로 이루어져야함!

 

 

 

 

 

 

https://inuplace.tistory.com/1005

 

[CoreData] 기초개념 (1): Entity, CRUD

CoreData란? Apple에서 제공하는 데이터관리 프레임워크로, 데이터를 유지 및 캐싱할 수 있을 뿐 아니라 Cloudkit을 사용해 여러 장치에 데이터를 동기화하는 것도 가능하다. 내부적으로 SQLite를 사용

inuplace.tistory.com

https://80000coding.oopy.io/72aca705-64d9-4be6-aaf5-34c1def4223a

 

(Swift) 코어 데이터 이해하기

"아래 모든 내용은 애플 공식 문서를 참고하여 정리 및 구현한 내용입니다."

80000coding.oopy.io

생각과 감정

오늘까지 졸업유예기간이다.. 유예는 하지 않겠다,,, wOO yEaH~,,,,

 

'TIL' 카테고리의 다른 글

TIL_20240116 iOS에서 데이터를 저장하는 방법  (0) 2024.01.16
TIL_20240110 Swift_AppSandbox, NSCoder  (0) 2024.01.10
TIL_20240109 Swift_SingletonPattern  (0) 2024.01.09
TIL_20240103  (0) 2024.01.05
TIL_20231226  (0) 2023.12.26

ToDo
✅ 운동
✅ 취지직...준비 
✅ 공부

 

글을 쓴지 조금 지났군요 하하 ^_^ 갑작스레 잡힌 면접을 준비하느라 공부는 살짝 미뤄뒀습니다.

솔루션 회사에 면접을 보고왔습니다만,, 여러 느낌은 제껴두고 면접관님에게 감사한 느낌이 듭니다. 

물론 합불을 떠나서 개발자로써 좋은 조언들을 해주시고 분위기도 편안하게 해주셔서 너무 감사드려요 ^_^/

하지만 저는 손에 땀이 너무 많이나더군요 하하.. 긴장했는지 발을 살짝 떨었는데 들킨거같은 느낌ㅋ

 

하튼~ 취준을 할때마다 느끼는 거지만 생각을 하면 할수록 머리가 복잡해집니다..~~

그래서 이제부터 스터디 카페에서 공부를 하려구요..ㅎ

타자를 좀 우다다다 치고싶지만 다른 공부하시는 분들을 위해 살살 누르는중..ㅋ

 

마저못한 CoreData와 데이터를 저장하는 방법들을 후다닥 알아봅시다~

 

배운점

UserDefaults

- 정보를 저장하고 검색하는 가장 일반적이고 편안한 방법

- 사용자 기본설정인 작은 정보 (ex. dark or ligh mode, volume크기(소리) 등) 를 저장할때 사용.

- 일반적으로 앱에 설정 화면이 있는 경우 UserDefaults가 적합

- 이는 Key-Value 로 property plist 또는 plist로서 disk에 저장된다.

- AppData > Library > Preferences 안에 plist 파일이 있는데 이게 표준 UserDefaults의 database 파일

 

Keychain

- 이는 disk에 있는 특수한 파일

- 암호화하고 보안을 유지해야 하는 작은정보 (ex. 암호, 자격증명, 토큰 등) 를 저장할때 사용

- 모든 것이 Data로 저장되어야 함. 따라서 해당 유형으로 직렬화 할 수 있는 object와 value만 전달해야함.

- 참고로 Keychain Sharing 을 활성화하려면 keychain에 저장한 값을 같은 팀에서 개발한 다른 앱과 공유 가능.

- ( 실제로 앱에서 키체인을 사용하려 한다면 좋은 라이브러리를 검색하여 그 라이브러리가 대신 작업을 해야 시간과 스트레스에 도움이 된다합니다 ^_^ 

 

File Sytem

- 저장해야하는 항목이 UserDefaults, Keychain에 해당하지 않는 경우 파일시스템 사용.

- 컴퓨터의 파일 시스템과 똑같이 작동하며, 경로와 URL을 사용하여 디스크의 리소스를 식별.

- 암호화 해야 하지만 키체인에 저장할 수 없는 대용량 파일의 경우 파일에 쓸 때 적절한 암호화 옵션을 사용하는 것이 좋음.

- 사용자의 진행 상황을 저장하기 위한 파일을 Library 폴더에 만들 수 있음.

- 앱의 파일 시스템은 샌드박스 처리됩니다. (링꾸)

 

언제사용?

- 웹에서 다운로드 한 이미지를 저장해서, 로딩 시간을 단축할 때는 Library/Caches 폴더 사용

- 앱에서 사용자가 콘텐츠를 만들 수 있도록 허용하는 경우 Document 폴더 사용 (ex. 사용자가 내보낼 수 있는 CSV 파일의 위치)

다만 동영상과 사진을 편집하는 경우 CameraRoll이 더 나은 선택.

 

sqlite

- 데이터를 저장하는 장소 이상으로 내부 데이터베이스의 사실상 표준.

- Library 폴더는 일반적으로 SQLite 데이터베이스를 저장하기에 가장 좋은 장소.

- 잘 구조화된 수많은 데이터가 있을때 사용하기 좋음

- 스토리지 기능 외에도 SQL 데이터베이스가 있으면 효율적인 검색이 가능하고 복잡한 쿼리를 작성하여 흥미로운 인사이트를 얻을 수 있음

 

CoreData

- Core Data는 iOS가 제공하는 ORM (Objected - Relational Mapping) 프레임 워크

- 데이터를 저장하고 관리하기 위한 프레임워크 즉 데이터를 조작하는 방법

- CoreData는 해당 기기에 데이터를 저장하므로 오프라인에서도 동작 가능하며,icloud에 데이터 공유 가능.

- SQL을 쓸 일 없이 오롯이 object - oriented 방식으로만 데이터를 다룰 수 있음. 데이터는 Object로 표현되며, 이러한 Object가 관계를 형성하어 Object Graphs를 이루고 이를 관리하는 프레임 워크가 바로 Core Data

- CoreData도 내부적으로는 SQL을 이용하여 데이터를 저장하지만, 개발자는 Xcode에 내장된 데이터 모델 에디터를 통해 데이터의 타입, 관계(Graphical Relationship)를 지정하고 코드로 관련 클래스를 수정할 수 있음.

- 우리는 Context에 의해 관리되는 DataModel을 만듦. 그리고 Context는 데이터 저장 및 검색을 담당하는 StorePresistor와 상호작용함.

- 여러 엔티티와 관계가 있는 복잡한 오브젝트 모델을 추적해야 할 때 좋음

- SQLite보다 더 빠르게 기록을 가져올 수 있지만, 더 많은 메모리와 저장 공간을 사용.

 

 

앞으로의 계획선언

CoreData부분은 더욱 알아봐야 할 것 같습니다. (persistentcontainer, context)등 아직 이해가 덜된것이 많군요

 

https://betterprogramming.pub/5-ways-to-store-user-data-in-your-ios-app-595d61c89667

 

5 Ways To Store User Data in Your iOS App

Choose the right storage based on your requirements

betterprogramming.pub

https://github.com/sujinnaljin/TIL/blob/master/Swift/5%20Ways%20To%20Store%20User%20Data%20in%20Your%20iOS%20App.md

https://80000coding.oopy.io/72aca705-64d9-4be6-aaf5-34c1def4223a

 

'TIL' 카테고리의 다른 글

TIL_20240119 iOS)CoreData로 부숴지기.. CRUD  (0) 2024.01.19
TIL_20240110 Swift_AppSandbox, NSCoder  (0) 2024.01.10
TIL_20240109 Swift_SingletonPattern  (0) 2024.01.09
TIL_20240103  (0) 2024.01.05
TIL_20231226  (0) 2023.12.26

ToDo
✅ 운동
✅ 공부

어제 하루 루틴을 조금 예상해보았지만.. 한두시간씩 밀리는 감이 있습니다 하하..

호다닥 공부를 해보겠습니다.

 

배운점

공부를 조금 진행하면서 간단한 앱을 만든적이 있습니다.

ToDoApp입니다. 하하

이 앱을 만들던중, 오늘 할일과 할일을 체크하는 두개의 기능이 있었지만, 앱을 껐다 키면 데이터가 모두 날아가,

UserDefaults를 사용해서 데이터를 저장하였습니다.

하지만 데이터를 저장하고 불러오는것은 성공하였지만, Todo의 체크여부가 셀이 늘어날수록 엉키고, 셀을 삭제했을때도 순서가 맞지않는 문제를 겪어, 체크박스를 커스텀해 제작을 했습니다!

 

하지만 공부를 하던중 이 이유를 알았습니다.. 바로 ReusableCell 때문이더군요! 테이블뷰를 스크롤 하여 내리면 새로 생기는 셀이 스크롤하며 보이지 않는 셀로 재활용 되어 나타나 체크가 되어있는 이슈였습니다.. 하하

이걸 알았다면 체크박스를 직접만드는 삽질은 안해도,, 또한 UserDefaults는 작은 정보만 저장을 하도록 추천을하고 UserDefaults 싱글톤으로 관리됩니다. 또한 UserDefaults를 사용하면 기본 자료형의 딕셔너리만 사용 할 수 있습니다.

따라서 데이터를 저장하는 방법을 NSCoder를 사용하여 바꾸었습니다. 


데이터를 plist로 저장하고 불러오기를 하기전 Sandbox의 개념을 알아보았습니다.

 

App Sandbox

: 앱이 손상된 경우 손상을 방지하기 위해 macOS 앱의 시스템 및 사용자 데이터에 대한 엑세스를 제한합니다.

 

프로그램을 보호하는 보안 모델로 보입니다!

 

 

 

앱을 다운받아 실행하면 이러한 화면을 많이 접합니다.

또한 Sandbox는 커널수준에서 시행되는 접근 제어 기술 이라고 합니다.

 

커널?? 메모리에 상주하는 운영체제의 부분

소프트웨어가 컴퓨터에서 실행되기 위해서는 메모리에 그 프로그램이 올라가있어야 합니다.

전원을 키자마자 OS또한 메모리에 올라갑니다.
하지만 OS 매우 커서 필요한 부분부분을 올리게 되는데 이때의 영역을 커널 이라고 합니다.

 

 

 

 

 

 

왼쪽 그림이 샌드박스가 없는 것이며 오른쪽은 샌드박스를 사용하는 앱의 경우 입니다.

 

왼쪽의 경우

앱을 실행하는 사용자는 모든 권한을 가지며, 사용자가 접근할 수 있는 모든 리소스에 접근을 할 수 있게 됩니다.

이는 보안의 허점이 있을 경우 앱의 취약점이 공격당할 수 있으며 공격자는 사용자가 수행할 수 있는 모든 작업을 수행할 수 있게 됩니다.

아주 악용하기 너무 좋아보이는걸요??

 

따라서 보안뿐 아닌 접근 문제또한 해결하기 위해 AppSandbox를 사용하는것 입니다.

 

1. AppSandbox를 사용하면 앱이 시스템과 상호작용 하는 방식을 설명합니다. ( 접근 권한을 앱에 부여하는것)

2. AppSandbox룰 사용하면 갤러리, 열기, 저장 등등 사용자 상호작용을 통해 앱에 투명하게 추가 접근 권한을 부여합니다.

 

App Sandbox의 원칙

:  App Sandbox는 각 앱마다 취약한 리소스에 대한 액세스를 제한함으로써 공격자로 인한 사용자 데이터 도난, 손상 또는 삭제 또는 시스템 하드웨어 해킹에 대한 마지막 방어선을 제공합니다.

하드웨어, 네트워크 연결, 앱 데이터, 사용자파일 등과 같은 리소스를 사용하기 위해서는 그 의도를 명시해야 합니다.

 

App Sandbox의 구조

샌드박스는 위와같은 내부 컨테이너로 볼 수 있습니다.

샌드박스에는 여러 디렉토리가 포함되어 있습니다.

 

Bundle Countainer

이곳은 앱의 번들 입니다. 이 디렉토리에는 앱 바이너라와 앱에서 사용되는 모든 리소스가 포함되어 있습니다.

이 디렉토리에는 write를 할 수 없습니다. 이 디렉토리에 write를 하면 서명이 변경되어 앱이 실행되지 않습니다.

(API를 사용하면 앱 번들에 저장된 모든 리소스에 대한 읽기 전용 액세스 권한을 얻을 수 있습니다.

 

DataCountainer

사용자가 텍스트 이미지 등을 저장하고 앱의 런타임 중에 생성된 데이터등 앱의 데이터를 저장합니다.

 

Document : 이 디렉토리를 사용하여 사용자 생성 콘텐츠를 저장합니다.

(iCloud를 사용하여 백업 가능)

 

Libary : 사용자 데이터 파일이 아닌 모든 파일의 최상위 디렉토리 입니다.

 

Temp : 이 디렉토리를 사용하여 앱 실행 간에 유지될 필요가 없는 임시 파일을 작성합니다.

(iCloud를 사용하여 백업 불가)

 

iCloud Container

런타임에 접근을 요청할 수 있는 추가 컨테이너 디렉토리입니다.

 

App Sandbox의 장점

- Sandbox는 앱의 데이터와 정보를 비공개 환경으로 보호하고 유지합니다.

- Sandbox는 시스템 리소스를 손상으로부터 보호함으로써 잠재적인 해커로부터 발생할 수 있는 피해를 최소화 할 수 있습니다.

- iOS or iPadOS 기기에 앱이 설치되면 시스템은 해당 앱에 대한 고유한 디렉토리를 생성합니다.

 

 

 


따라서 App Sandbox덕분에 앱이 수명 내내 파일에 저장된 데이터를 읽기,쓰기를 할수 있습니다.

 

 

ReusableCell을 사용하지 않기 위해 데이터 모델을 만들어주었습니다.

import Foundation

class Item: Codable {
    var title: String = ""
    var done: Bool = false
}

 

할일인 title과 체크여부를 알려주는 done을 작성하였습니다.

 

Codable을 사용하여 plist로 [Item]타입의 배열을 저장하려 합니다.

 

plist가 저장되는 장소는

let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("Items.plist")
print(dataFilePath)

위의 코드로 알 수 있습니다.

 

//    addButtonPreesed에서 plist를 저장하게된다면 title은 저장이됨, 하지만 done 즉 체크를 판단하는 부울은 저장이 안됨
//    이는 didSelectRowAt안에서또한 저장을 해야함. 따라서 같은 코드를 복붙X 함수를 만들어 사용
func saveItems() {

    let encoder = PropertyListEncoder()

    do {
        //데이터 인코딩
        let data = try encoder.encode(itemArray)
        //dataFilePath에 items.plist 생성
        try data.write(to: dataFilePath!)
    } catch {
        print("Error encoding item array, \(error)")
    }

    //테이블뷰에 itemArray의 내용의 셀을 보기위한 리로드
    self.tableView.reloadData()
}

//plist에 저장된 data 가져오기
func loadItems() {
    if let data = try? Data(contentsOf: dataFilePath!) {
        let decoder = PropertyListDecoder()
        do {
            //데이터파일 패스에서 데이터를 디코딩하는 메서드
            itemArray = try decoder.decode([Item].self, from: data)
        } catch {
            print("Error decoding item array, \(error)")
        }
    }
}

 

PropertyListEncoder와 PropertyListDecoder

PropertyListEncoder는 Encodable 프로토콜을 따르는 데이터 타입을 PropertyList형식으로 인코딩 할 수 있게 됩니다.

PropertyListDecoder는 반대로 Data를 Decodable 프로토콜을 따르는 타입으로 디코딩 할 수 있도록 해줍니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

https://medium.com/techiepedia/demystifying-ios-ipados-sandbox-with-swift-code-8c9222d19380

 

Demystifying iOS/iPadOS SandBox with Swift Code

Hello everyone in this article we are going to see what is iOS Sand Box and how does it works and how developers can access their app’s…

medium.com

https://developer.apple.com/documentation/security/app_sandbox#//apple_ref/doc/uid/TP40011183-CH1-SW1

 

App Sandbox | Apple Developer Documentation

Restrict access to system resources and user data in macOS apps to contain damage if an app becomes compromised.

developer.apple.com

 

생각과 감정

어.. 요즘 갑자기 모든것이 2배속으로 느껴질때가 있더군요 검색을 해보니 스트레스 때문이라던가~ 저는 아니라고 생각해왔지만

막상 받긴 받나 봅니다 허허,, 구래도 정진... 해야겠지..?

부지런하려 노력한 나에게 감사해...🙏

 

 

'TIL' 카테고리의 다른 글

TIL_20240119 iOS)CoreData로 부숴지기.. CRUD  (0) 2024.01.19
TIL_20240116 iOS에서 데이터를 저장하는 방법  (0) 2024.01.16
TIL_20240109 Swift_SingletonPattern  (0) 2024.01.09
TIL_20240103  (0) 2024.01.05
TIL_20231226  (0) 2023.12.26

ToDo
✅ 운동 clear~
✅ 나태지옥 빠져나가기
✅ 졸업신청인가 유예인가?

✅ Swift singleton pattern 공부

 

후 오픽 점수를 IM2를 받아 졸업을 할수 있게 되었습니다만.....

과연 졸업을 하는것이 맞는것인가? 졸업유예를 하는것이 맞는것인가?? 허허..

어떻게 생각하시나요?

저는 아직 모르겠습니다만...

둘다 이후에 행적은 비슷할것 같지만 어떤것이 더욱 유리할까요~!~! 유리...라,,,,

이득? 흠... 뭐 비슷비슷 할것 같습니다만~!~

유예신청 기간에 생각좀 해보겠습니다..ㅎ

 

하루 루틴을 예상하고 내일부터 지켜보도록 하겠습니다. (자세한 일정은 추가하지 않는다.. 나는 극Pㄷ,,)

8시쯤 느지막하게 기상 후 식사

9시 운동출발

11시 집도착

12시 점식먹고

13시 유데미 강의 때리기 (틈틈히 쉬기)

16시 cs공부

18시 or 19시 저녁

~휴식

22시  인턴/신입 공고 구경 코테한문제 때리기?

24시 or 01시 취침

 

이렇게 보니 흠 너무 계획이 난장판이군요...

조금더 자세하게 정리하고 지켜나가 보겠습니다. 일단 저건 초안 ㅋ

배운점

UserDefaults를 이전에 간단한 TODO앱을 만들때 공부하였습니다만!

오늘 Udemy강의에서도 todo앱을 만들면서 싱글톤 패턴이 나와

싱글톤패턴을 공부해보았습니다..하하

 

싱글톤 패턴(Singleton pattern)

특정 용도로 객체를 하나만 생성하여, 공용으로 사용하고 싶을 때 사용하는 디자인 유형. 이라고 정의되어있습니다.

또는 한 개의 클래스로 만드는 객체는 단 한개여야만 한다는 규칙을 가진 디자인 패턴 입니다.

 

프로그램 전체에 단 하나의 전역 객체를 만들어놓고 다른곳에서 이 하나의 객체에 접근하는것 입니다.

 

EX)

URLSession.shared : 네트워크 처리를 할 때 URLSession 객체를 이용하는데, 이미 만들어져 있는 shared 객체에 접근해 메서드를 수행한다.

UserDefaults.standard : UserDefault에서 기본적으로 공유하고 있는 standard 저장소에 접근해 쓰고 읽기 위해 만들어져 있는 standard 에 접근해 메서드를 수행한다.

 

이 위 두예시가 싱글톤 패턴을 기반으로 만들어졌다고 생각하면 된다 합니다 ㅎㅎ

 

import UIKit

//Car 클래스는 빨간색 색상을 가지고, static let으로 만들어진 Car()의 객체인 singletonCar를 만듭니다.
class Car {
    var colour = "Red"
    
    //싱글톤 인스턴스를 저장하는 static상수
    static let singletonCar = Car()
}

let myCar = Car.singletonCar
myCar.colour = "Blue"

//인스턴스 공유 
let yourCar = Car.singletonCar
print(yourCar.colour) //yourCar도 같은 싱글톤 인스턴스를 참조하므로 "Blue"가 출력됩니다.

class A {
    init() {
        Car.singletonCar.colour = "Broun"
    }
}

class B {
    init() {
        print(Car.singletonCar.colour)
    }
}

let a = A()
let b = B()

//A클래스의 인스턴스를 생성하며 색상을 Brown으로 변경됩니다.
//B클래스의 인스턴스를 생성하면서 색상을 출력합니다. "Brown"출력

 

 

결과적으로 싱글톤 패턴을 사용하면 언제나 동일한 Car객체에 접근할 수 있으며, 객체의 상태를 전역적으로 관리할 수 있습니다.

위의 코드에서 볼 수 있듯이 여러 클래스에서 해당 싱글톤 인스턴스를 공유하고 상태를 변경할 수 있음을 보여줍니다.

 

위와같이 강의를 보며 싱글톤 패턴을 이해하였는데요! 

다른 블로그를 구경하며 다른 예제를 보며 이해를 도왔습니다.

 

class UserInfo {
    var id: String?
    var password: String?
    var name: String?
}

 

User의 정보를 저장하는 UserInfo라는 클래스를 선언합니다.

 

//A ViewController
let userInfo = UserInfo()
userInfo.id = "Sodeul"

//B ViewController
let userInfo = UserInfo()
userInfo.password = "123"


//C ViewController
let userInfo = UserInfo()
userInfo.name = "Sodeul"

 

A,B,C ViewController에서 각각의 UserInfo객체를 만들어서 저장하면,

각 인스턴스의 프로퍼티에만 저장이되며 데이터는 공유할 수 없게 됩니다.

 

따라서 UserInfo에 대한 인스턴스는 최초 생성될 때 딱 한번만 생성해서 전역으로 선언하고 이후에 이 인스턴스만 접근 가능하게하자

--> 이 말이 Singleton Pattern 입니다.

 

따라서 

class UserInfo {
    static let shared = UserInfo()

    var id: String?
    var password: String?
    var name: String?
    
    private init() { }
}

 

static을 이용해 인스턴스를 저장할 shared라는 프로퍼티를 생성합니다.

이후에 혹시 init를 호출해 인스턴스를 또 생성하는 것을 막기위해 init의 접근제어자를 private로 지정합니다.

 

위와같이 싱글톤을 만들수 있습니다.

 

외부에서의 접근은 

//A ViewController
let userInfo = UserInfo.shared
userInfo.id = "Sodeul"

//B ViewController
let userInfo = UserInfo.shared
userInfo.password = "123"
 
 
//C ViewController
let userInfo = UserInfo.shared
userInfo.name = "Sodeul"

 

어느 ViewController에서든 shared라는 프로퍼티에 접근하면 하나의 인스턴스를 공유합니다.

 

그럼 싱글톤패턴에 대해 알아봤으니 장/단점 또한 알아 보겠습니다 ㅎㅎ

 

싱글톤 패튼의 장/단점

장점

- 메모리를 단 한번만 사용한다.

해당 객체는 단 한번만 만들어지기 때문에 메모리 관리가 편하다는 장점이 있습니다.

 

- 객체 접근 시간이 줄어든다.

다시 메모리를 할당하고, 초기화(init)하는 시간이 줄어드니 한번 만들어 두기만 하면

다시 접근할 때 매번 객체를 만드는 것보다 조금이나마 시간이 빠르다.

 

- 전역 번위에서 상태, 데이터 전달이 쉬워진다.

어디에서든 접근할 수 있기 때문에 데이터를 전달할 수 있다.

 

단점

 

- 테스트가 힘들다.

싱극톤 클래스는 초기화를 private로 선언합니다.

이렇게 한다면 테스트용 Mock 객체를 만들어내기 어려워진다.

 

- 의존성을 만들어낸다.

어디에서나 접근을 할 수 있으니 어떤 객체와 연결되어 있는지 다 찾아내기 힘들어진다.

 

- 멀티 스레드 환경에서 위험할 수 있다.

멀티 스레드 환경에선 싱글톤 객체가 2개가 생기는 문제가 발생할 수 있다.

또한 싱글톤 객체 내부의 데이터를 동기적으로 처리하지 않으면 여러 객체가 동시에 사용되다 꼬여버릴수 있다.

 

 


테스트용 Mock 객체..?? 

: Swift에서 Mock 객체는 주로 단위 테스트를 수행할 떄 사용되는 가상의 객체라고 합니다!

이 객체는 실제 객체를 모방하여 특정 동작을 시뮬레이션 하거나 메서드 호출을 기록하고 검증하는데 사용된다 하군요.

주로 의존성 주입 패턴과 함께 사용되어 코드의 격리성을 유지하고 테스트 가능한 코드를 작성하는데 도움이 된다고 합니다.

(링크)

 

생각과 감정

생각과 감정이라.. 하하 위에서 다 말을 해버려서 훠훠

 

앞으로의 계획선언

이제 더는 학생이 아닐수도..? 하지만 배움엔 끝이없죠 매일 꾸준이 공부하다 보면 좋은 기회가 있을거라 생각합니다 ㅎㅎ

항상 열심히 정진 하겠습니다.

오늘만큼은 부지런했던 나에게 감사해...🙏

 

 

 

 

https://stackoverflow.com/questions/137975/what-are-drawbacks-or-disadvantages-of-singleton-pattern

 

What are drawbacks or disadvantages of singleton pattern?

The singleton pattern is a fully paid up member of the GoF's patterns book, but it lately seems rather orphaned by the developer world. I still use quite a lot of singletons, especially for factory

stackoverflow.com

 

https://babbab2.tistory.com/66

 

Swift) 싱글톤 패턴(Singleton Pattern)

안녕하세요 :) 소들입니다 이번 포스팅에선 싱글톤 패턴이 무엇이고, Swift에선 어떻게 사용되는지에 대해 알아보려고 해요!!! 왜 네트워크 하다가 갑자기 SingleTon이냐 하면 내 마음임 모든 포스팅

babbab2.tistory.com

 

https://medium.com/hcleedev/swift-singleton-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4-b84cfe57c541

 

Swift: Singleton, 싱글톤 패턴

Singleton 패턴은 무엇인지, 장단점을 알아보고, Semaphore를 이용한 사용 예시까지 살펴보자.

medium.com

 

'TIL' 카테고리의 다른 글

TIL_20240116 iOS에서 데이터를 저장하는 방법  (0) 2024.01.16
TIL_20240110 Swift_AppSandbox, NSCoder  (0) 2024.01.10
TIL_20240103  (0) 2024.01.05
TIL_20231226  (0) 2023.12.26
TIL_20231223  (0) 2023.12.23

ToDo
✅ udemy swiftUI강의
✅ 운동
✅ 나태한 나를 반성하기.

 

흠 오늘은 어제 유데미 강의를 보며 클론한 코드를 다시 하나씩 뜯어보며 

사용된 내용들을 잘근잘근 씹어서 삼켜보도록 하겠습니다..

 

배운점

Hacker News를 볼수있는 간단한 앱을 클론 했습니다만,,~~

networking, URLSession, Json decode등을 알수 있었쥐만,,,~~

네트워킹 부분에서 https://news.ycombinator.com/ 의 제목, id 등등을 가져와야 했습니다.

이 과정에서 항상 썼던 

class NetworkManager: ObservableObject {
    
    @Published var posts = [Post]()
    
    func fetchData() {
        if let url = URL(string: "https://hn.algolia.com/api/v1/search?tags=front_page") {
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { data, response, error in
                if error == nil {
                    let decoder = JSONDecoder()
                    if let safeData = data {
                        do {
                            let results = try decoder.decode(Results.self, from: safeData)
                            DispatchQueue.main.async {
                                self.posts = results.hits
                            }
                        } catch {
                            print(error)
                        }
                    }
                }
            }
            task.resume()
        }
    }
}

 

위의 fetchData()의 함수부분을 생각없이 코드를 집어넣었지만 한줄 한줄 뜯어 보다보니, 잊고있었던

async await의 개념을 공부하게 되었습니다.

 

async await을 공부하기 위해 이 블로그를 보며 공부를 하는 중이었지만,, 처음 보는 부분이라 이해가 잘 되지 않더라구요..
그래서! 기억난 async swift에서 발표하신 내용을 확인후 다시 블로그를 보며 공부 했습니다...
(진짜 이 발표 이해 굳굳으로 됨... 발표도 그렇고 블로거 수진님...정말 캄사함다.. 저도 블로그 짜집기 하며 정리를 해보겠슴다..) 

 

DispatchQueue.main.async

 

Swift의 코드는 한줄의 코드가 문장처럼 읽히게 작성 한다라고 어디서 주워 들었던것 같네요..ㅎㅎ
(궁금하면 다시 코드 컨벤션을 찾압 보겠습니다.)

 

하튼 DispatchQueue 큐로 보낸다는 뜻인것 같군요.

main 메인 으로 보낸다는것 같군요.

async 방식으로 한다는것 아닐까요?

메인 디스패치큐에 비동기로 task를 보낸다는것 같군요!!

 

네... ~~인것 같아요 ㅋㅋ

 

이글은 누구에게 async await을 알려주는 글이 아닌 오로지 저의 이해를 위한 글이니 다른

사람에 편의는 봐주지 않겠습니다..(하하..봐줘,,)

 

 

비동기(async)

메인 스레드가 자기한태 쌓여있는 다음 일을 실행한다.. 다음 라인을 실행한다 라구요..

queue에 보낸 작업은 생각하지 않고 바로 그 다음일을 한다 입니다..

 

동기(sync)

queue에 보낸 작업이 완료 될 때까지 기다린 후 다음 줄로 넘어갑니다.

 

queue.async { task } 또는 queue.sync { task }로 task를 queue로 보냈습니다.

queue에 쌓여있는 task들을 다른 스레드에 넣어 일을 해야겠습니다.

 

------------------------------------------------------------------------------

여기서 두개의 큐의 방식이 나오게 됩니다.

 

Serial(직렬)

serial queue는 한대의 스레드에서 처리하는 큐 입니다.

(여러개의 스레드가 있어도 한개의 스레드만 사용을 하는것 입니다.)

 

Concurrent(동시)

concurrent queue는 여러개의 스레드에서 처리하는 큐 입니다.

 

두개의 큐 방식중 어떤것을 사용해야 하는가??( 난 몰루? 항상 빠른것이 짱임 ㅋㅋ)

순서가 중요한 작업이면 serial queue, 순서가 중요하지 않고 빨리 끝내야 하는 작업이면 concurrent queue방식을 

사용 해야 한다고 하네요 껄껄

 

async sync, serial concurrent를 두개씩 묶어 생각하지 않고 별도의 개념으로 받아드려요,,,

 

async, sync -> 작업을 보내는 시점에서 기다릴지 말지에 대해 다루는것

 

serial, concurrent -> 큐에 보내진 작업을 여러개의 스레드에 보낼지 한개의 스레드로 보낼지에 대해 다루는 것

 

 

 

Dispatch Queue의 종류

 

1. main Queue

: 오직 한개만 존재하는 큐, Serial의 특성을 가짐, 이곳에 할당된 task는 메인 스레드에서 처리(UI 업데이트 내용 처리)

 

2. global Queue

: concurrent의 특성을 가진 큐, QoS(qualith of service)에 따라 여러개의 종류로 나뉨.

 

QoS(qualith of service) 6종에 대해 또한 알아야 겠습니다.

 

- userInteractive

사용자와 직접 상호작용 하는 작업 ( UI업데이트, 애니메이션 등)

메인스레드에서 처리하면 많은 로드가 걸리는 작업을 userInteractive에서 처리하여

바로 동작하는 것처럼 보이게함.

 

- userInitiated

클릭과 같은 즉각적인 결과가 필요한 작업(저장된 문서열기 등..)

userInteractive보다는 조금 오래걸리고 유저가 어느정도 인지하고 있음

 

- default

일반적인 작업

 

- utility

progress bar와 함께 길게 싱행되는 작업 (데이터 다운로드 등,,,)

 

- background

유저가 인지하지 않는 시간이 덜 중요한 작업(동기화 및 백업 등,,,)

 

- unspecified 

Qos 정보가 없음 을 나타냄. (거의 사용할일 없다십니다 하하)

 

 

3. custom Queue

: 커스텀으로 생성, 디폴트로 Serial의 특서을 가진 큐 but Concurrent로 설정이 가능하다.

 

앞으로의 계획선언

요즘 공부에대한 목적을 잃고 다시 나태지옥에 빠지는 듯한 기분이 듭니다.. 

그래서 ios공부와 같이 플러터또한 시작해볼까 합니다.. 핳하...

뭐라도 하면서 흥미를 붙여야 좋지 않을까 합니다 하하..

'TIL' 카테고리의 다른 글

TIL_20240110 Swift_AppSandbox, NSCoder  (0) 2024.01.10
TIL_20240109 Swift_SingletonPattern  (0) 2024.01.09
TIL_20231226  (0) 2023.12.26
TIL_20231223  (0) 2023.12.23
TIL_20231221  (0) 2023.12.21

ToDo
✅ 운동
✅ OPIC 개노쥄..

 

30일에 오픽을 결제하고 미친 벼락치기를 하는중입니뒈....

토익은 시간이 조금 걸리니 졸업을 위한 벼락치기..ㅋㅋㅌ

잘못은 제가 많이했습니다.. 졔송함다...

 

배운점

 

오픽노잼님의 영상을 보며 꿀팁을 조금 흡수했습니다.

오픽노잼,,,

Im 시리즈 001

AVA : i would like to know where you live

  • describe your home
  • what does it looks like?
  • how many rooms does it have?
  • give me a description with lots of details.

학생 :

Oh, you wanna know about my palce? Ok.

bascially, i live in 4-story house.

this place very small place.

looks like, maybe… a shoebox?

so,,, but,,, this palce very, very comfortable and cozy because only focus me. focus to me.

And so, this place nearby university 공주.

very, very good. Favorite

so, i gruated university 공주.

so, this place very looks like,,, uh, like, i feel so comfortable.

That’s all

Rule 1. Ava에게 질문하지 않기. 질문할때는, 수사학적 질문으로.(대답이 필요없는 질문)

Oh, you wanna know about my palce? Ok. → 어색한 질문을 던짐

질문을 던지는것보단 인정하는것.

Oh, so you wanna know about my palce? Alright, well~

⇒ 상대방이 무언가를 원하고 있다는 것을 알아차리고 응답을 할때 사용한다.

Rule 2. 불편한 어려운 단어 사용하지 않기! 사용하기 편하고 간단한 단어 사용하기.

bascially, i live in 4-story house.

4-story house. 은 4층집.. ㅋ 어려운 단어를 잘못씀

⇒ my home is really small. 같이 간단한 단어 사용

(house는 apartment와 구별하는 단어 따라서 Home사용)

this place very small place.

⇒ this place 로 자신의 집이 아닌 느낌이 남.

따라서 it’s very small place, my place is a very small place 등 사용

Rule 3. 한문장에 같은단어 반복하지 않기.

this place very small place. : place를 두번 사용함

Rule 4. 무언가 묘사하거나 감정 단어를 2개이상 말할때 “AND” 사용하지 않기.

and를 사용하면 스크립트를 외워서 말하는것 같음.

한문장을 두문장으로 말하기.

so,,, but,,, this palce very, very comfortable and cozy because only focus me. focus to me.

⇒ my room is just so, you know, comfy. it’s mean cozy!

Rule 5. 한가지에 대해서만 말하기! (주제에서 벗어나지 않기.)

다른 이야기를 덧붓이거나 관련 없는 이야기는 흐름을 방해하므로 한가지 주제만 이야기 한다.

한가지 주제를 선택하고 1분동안 마인드 맵을 그리며 이야기한다.

And so, this place nearby university 공주. ~~ 주제에 벗어남.

Im 시리즈 002

자신이 IL 아니면 IM1 이다. ⇒ 3선택X 적어도 난이도 4이상을 선택!! 더높은 점수를 받을 확률이 높아짐.

AVA : What is your normal routin at home? (집에서 평소에 뭐하시나요?)

  • What thing do you usually do on weekdays and what kinds of things do you go on weekends? (평일과 주말엔 뭐하시나요?)

⇒ A 평일엔 뭐해? B: 주말엔 뭐해? A,B둘중 하나 선택후 ex) A 1% B 99% 대답하기!

학생 :

um, I’m a student so i spend time at library on weekdays, yeah.

you know, i didn’t have much time on weekdays.

but instead, i usually spend time at home on weekend, yeah.

i love this time because i can do everything what i want, yeah.

but you know what?

i love watch movies.

so, i usually watch movies at home.

if makes me flexed, yeah.

quite good. um.

the another thing is…

Um, you know, the another thing is listen to music, catch some z’s, and so on, yeah

these things are makes me full of energy.

⇒ A 평일엔 뭐해? B: 주말엔 뭐해? A,B둘중 하나 선택후 ex) A 1% B 99% 대답하기!

you know, i didn’t have much time on weekdays.

나는 평일 이야기 는 조금하고 주말만 이야기 하겠다, 그래도 평일 약간 설명하기.

  • Im barely home
  • Im rarely home
  • im like never home
  • i only come home to sleep

so, i usually watch movies at home.

( 덧붙이기)

And so, that is what i usually do at home at on weekends.

if makes me flexed, yeah.

⇒ it helps me to relax. it makes me feel so good to watch movies all day.

Um, you know, the another thing is listen to music, catch some z’s, and so on, yeah

Rule 2. 불편한 어려운 단어 사용하지 않기! 사용하기 편하고 간단한 단어 사용하기.

the another thing is…~~

Rule 5. 한가지에 대해서만 말하기! (주제에서 벗어나지 않기.)

를 어기고있음.

⇒ 긴장해서 다른이야기를 하거나 말이안나옴.

Rule 6. 긴장이 되고 할말이 없을땐, 바로 결론으로 말하기.

아무말이 안나오면 바로 결론으로 말하고 끝내기.

Hbit 카테고리에서 (how to talk more!)

아무말이 안나온다!

  • Quick comparison 빠른 비교

it helps me to relax. it makes me feel so good to watch movies all day.

이 문장 뒤에 진짜 말이 나오지 않는다면 결론으로 가기.

하지만 연습을 할땐 “Hbit”의 전략을 생각하기. (Quick comparison 빠른 비교)

빠른 비교 : 잠깐 과거로 갔다가 현재로 오는것,

ex) 예전엔 이랬지만 지금은 이렇다.

I never did this before, but nowdays, i just love doing this!

  • i just dont know why!, i just cant explain it!

more hard)

its funny… i never really did this before, but nowadays, i just love doing this

따라서 이학생은 Rule 2, 5, 6 를 어겼다..

Im 시리즈 003

AVA : describe the home you lived in as a child.

  • how was that home differnt from the home you live in now?
  • 어렸을때, 살았던 집에 대해 말해주세요.

학생 :

My childhood's home... Oh, actually I can't remember very specifically, but one thing I just remember very clearly it was so huge house.

Sofa, furnitures, chairs, desks... everything

was so huge. So big. It's feels like I was a ant. Because I think I was a little girl that's why l feeled like everything was so big.

Now, l'm live in more big house. But I'm still need more place. I feels it's not bigger than when I kid is. Oh, maybe I'm growing so that's why I feels like it.

Rule 7. “솔직한 변명”은 나중에 하기. 처음 부분에 하지 않기.

오픽 대답을 할때, 솔직하게 말하는 것이 훨씬 좋다.

선의의 거짓말 또한 좋다,

하지만 다른사람의 스크립트 외워서 하는건 비추 (거짓말 하는것이 더욱 어렵기 때문)

My childhood's home...

질문에 있는 단어를 말하면서 생각하는 모습을 보여줬다.

 

생각과 감정

초중고를 합하면 12년을 영어를 배웠지만,, 말을 잘못하네 내가..?하하

들리기는 하지만 입으로 잘 나오지 않고 생각하는 말이 뜻대로 전달이 안되는군요..

영어마스터 하는 그날까지.. 화이팅!!(그날이 언제임.?)

 

 

 

'TIL' 카테고리의 다른 글

TIL_20240109 Swift_SingletonPattern  (0) 2024.01.09
TIL_20240103  (0) 2024.01.05
TIL_20231223  (0) 2023.12.23
TIL_20231221  (0) 2023.12.21
TIL_20231212  (0) 2023.12.12

ToDo
✅ 운동
✅ 치즈케이크먹기 ㅋ

 

SwiftUI를 공부흐는 증읍느드.... uikit보다 재미가 느껴지네욤 아직 uikit은 마스터하진 못하였지만

흥미도 조금있어야 스트레스를 덜받겠죠 ㅎ.. 암튼~

곧 있으면 크리스마스네요 ^_^ 모두들 메리 크리스마스~~ (이브와 당일엔 등장하지 않습니다..)

 

배운점

https://simth999wrld.tistory.com/60

 

TIL_20231113

짧은인사, 하루의 사건, 나의 행동 ToDo ✅ udemy 완강 끄읕 ✅ 패캠 강의 ✅ 운동 가을은 어디갔죠...? 하ㅏㅎ... 날씨가 이리 추울 수 있나요ㅋㅋ 열어분 모두 감기 조심하세요~~ 또 건조해져서 가습

simth999wrld.tistory.com

 

오늘은 SwiftUI의 Property Wrappers를 알아보았습니다. 이걸 모르면 아무것도 못하것죠??

한번 보았던 내용이니 후딱 하고 넘어가겠습니다. 리마인드 하는 마음으로 보자구요

Property Wrapper

반복되는 코드를 간단하게 적용하기 위해 사용되는 문법입니다.

 

 

 

@State

 

@State는 특적 프로퍼티를 뷰의 상태(state)로 만들어줍니다.

무슨소리일까요??

간단하게 변수값이 변경이 되면 자동으로 뷰도 변경이 일어납니다.

 

@State var leftDiceNumber = 1
@State var rightDiceNumber = 1

var body: some View {
    DiceView(n: leftDiceNumber)
    DiceView(n: rightDiceNumber)

    Button {
    self.leftDiceNumber = Int.random(in: 1...6)
    self.rightDiceNumber = Int.random(in: 1...6)

    } label: {
        Text("Roll")
    }
}

 

간단한 코드입니다. VStack등 제끼구 봅시다.

 

leftDiceNumber와 rightDiceNumber는 @State로 선언되어 있습니다.

"Roll"의 버튼이 눌리게 된다면 1~6의 숫자가 랜덤하게 들어가며 주사위의 이미지가 바뀌게 됩니다.

 

만약 @State로 선언되어 있지 않다면 아무리 Roll을 하게되더라도 데이터와 뷰가 바뀌지 않게됩니다.

 

 

 

@Binding

 

@Binding은 다른 인스턴스 소유의 @State 프로퍼티를 가져올때 사용합니다.

struct MyToggleButton: View {
    @Binding var value: Bool

    var body: some View {
        Button(action: {
            self.value.toggle()
        }, label: {
            Text(self.value ? "Hello" : "World")
        })
    }
}

struct ContentView: View {
    @State private var value = false

    var body: some View {
        VStack {
            MyToggleButton(value: $value)
        }
    }
}

위의 코드에서 MyToggleButton의 struct의 value 프로퍼티가 @Binding으로 선언되어있습니다.

이 프로퍼티는 ContentView에서의 뷰가 생성될때 value프로퍼티와 연결되게 됩니다.

 

따라서 두 데이터는 연결되어 한쪽값이 바뀌어도 다른 한 값이 바뀌게 됩니다. 뷰또한 업데이트 됩니다.

 

@State, @Binding은 value타입 즉 값 타입이기에 reference type참조 타입일때는 사용을 하지 못한다는 단점이 있습니다.

참조타입인 클래스에선 사용을 하지 못합니다.

 

 

@ObservedObject

 

@ObservedObject 라는 Property Wrapper를 사용하여 @State, @Binding의 단점을 극복할 수 있습니다.

@ObservableObject를 상속받은 클래스의 프로퍼티는 @ObservedObject 의 프로퍼티 래퍼를 적용하여 뷰와 프로퍼티를 연결시킬수 있습니다.

추적을 원하는 프로퍼티는 @Published의 프로퍼티 래프를 작성해야 합니다.

class MyData: ObservableObject {
    @Published var name = "World"
    @Published var buttonTitle = "Switch to Universe"

    func switchName() {
        if name == "World" {
            name = "Universe"
            buttonTitle = "Switch to World"
        } else {
            name = "World"
            buttonTitle = "Switch to Universe"
        }
    }
}

struct ContentView: View {
    @ObservedObject var data = MyData()

    var body: some View {
        VStack {
            Text("Hello, \(data.name)!")
                .padding()
            Button(
                action: { self.data.switchName() },
                label: { Text(self.data.buttonTitle) }
            )
        }
    }
}

 

 

 

@EnviromoentObject

@EnviromoentObject는 클래스 오브젝트를 추적하기 위한 용도의 프로퍼티 래퍼이다.

ObservableObject를 통해 구현된 타입의 인스턴스를 전역으로 공유하여 사용

앱 전역에 공통으로 사용할 데이터를 주입 및 사용

class SharedData: ObservableObject {
    @Published var configName = "default"
    ...
}

struct ContentView: View {
    @EnvironmentObject var sharedData: SharedData
    ...
}

struct FooView: View {
    @EnvironmentObject var sharedData: SharedData
    ...
}

SharedData를 ObservableObject로 선언후, ContentView와 FooView에서 @EnviromoentObject의 형식으로

참조한다. 이는 여러 곳에서 공유될 만한 데이터를 관리하는 모델로 사용하기 좋다.

 

SharedData를 참조가 시작되기 전에 생성해야한다.

보통은 해당 뷰를 만들기 전에 오브젝트를 생성하고 이것을 enviromentObject()로 알려주어야 한다.

 

var sharedData = SharedData()
...
window.rootViewController =
    UIHostingController(rootView: ContentView().environmentObject(sharedData))

위의 코드가 SharedData 오브젝트를 생성해서 공유를 시작하는 시점이다.

 

SceneDelegate.swift에서 설정.

https://leetaek.tistory.com/67

 

 

 

 

@StateObject (https://pilgwon.github.io/post/state-object-vs-observed-object)

@StateObject는 @ObservedObject와 비슷한 특징을 가졌지만 SwiftUI의 라이프싸이클을 관리하는 

방식에 차이점이 있습니다.

 

뷰에서 ObservableObject 타입의 인스턴스 선언 시 사용할 수 있음.

 

뷰마다 하나의 인스턴스를 생성하며, 뷰가 사라지기 전까지 같은 인스턴스 유지

@ObservableObject의 뷰 렌더링 시 인스턴스 초기화 이슈 해결을 위한 방법

 

매번 인스턴스가 새롭게 생성되는것처럼 외부에서 주입 받는 경우가 아닌 최초 생성 선언 시에 @StateObject를 사용하는 것이 적절한 방법

 

위의 특징이라 저번TIL에 작성을 하였었는데, 흠 너무 추상적으로 적어두어서 다시보니 이해가 가질 않습니다.

 

SwiftUI가 화면을 만들거나 다시 그릴수 있는 가능성이 있다면 인스턴스가 초기화가 되지 않는 @StateObject를 사용한다고

다시 이해를 하였습니다 ^_^

의존 관계로 주입한다면 @ObservedObject

 

생각과 감정

고독합니다.. 고독.... 누군가와 같이 스터디를 하고싶슴다... 프로젝트도 하고싶고... 으악...

앞으로의 계획선언

일단 크리스마스를 즐겨보자구요 ^_^

 

 

 

 

 

(보면서 공부했슴다.. 감삼다!)

https://seorenn.github.io/note/swiftui-property-wrappers.html

 

SwiftUI Property Wrappers - Seorenn Note

@State 는 특정 프로퍼티를 뷰의 상태(state)로 만들어준다. 즉 이 프로퍼티가 변경되면 자동으로 뷰의 데이터도 변경되고, 뷰의 데이터를 바꿔도 이 프로퍼티의 데이터도 자동으로 변경된다. struct

seorenn.github.io

 

'TIL' 카테고리의 다른 글

TIL_20240103  (0) 2024.01.05
TIL_20231226  (0) 2023.12.26
TIL_20231221  (0) 2023.12.21
TIL_20231212  (0) 2023.12.12
TIL_20231126  (0) 2023.11.26

흐아.. 아무것도 하기 싫지만 일단 의자에 앉았으니 뭐라도 해야겠죠..?

ㅋㅋㅌ 그동안 uikit만 공부를 했지만,, 패캠에서 산 강의는 SwiftUI이기에,, 기초를 다듬으러

다시 안젤라의 강의를보며 SwiftUI의 기초를 다듬어 보겠~~~~~~~습니다~~

 

 

배운점

preViewDevice

#Preview {
    ContentView().previewDevice(PreviewDevice(rawValue: "iPhone SE"))
}

프리뷰에 디바이스를 다른것으로 확인 하기 위해선 위와 같은 코드로 설정을 하여 확인을 한다.

 

xcrun simctl list devicetypes

위의 코드를 터미널에 입력하면 rawValue에 들어갈 수 있는 장치를 나열하여 알려줍니다 ^_^

 

iPhone 6s (com.apple.CoreSimulator.SimDeviceType.iPhone-6s)

iPhone 6s Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus)

iPhone SE (1st generation) (com.apple.CoreSimulator.SimDeviceType.iPhone-SE)

iPhone 7 (com.apple.CoreSimulator.SimDeviceType.iPhone-7)

iPhone 7 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-7-Plus)

iPhone 8 (com.apple.CoreSimulator.SimDeviceType.iPhone-8)

iPhone 8 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus)

iPhone X (com.apple.CoreSimulator.SimDeviceType.iPhone-X)......

(아이폰 뿐아닌 패드, 워치, 티비등의 장치를 알려줍니다.)


⌘ + ctrl + L 을하여 오브젝트 라이브러리를 확인할 수 있습니다.

(각 오브젝트의 modifier들 또한 확인할 수 있습니다.)

 

 

modifier는 메서드의 아랫줄의 개행을 하여 작성한다. (가독성을 위해)

struct ContentView: View {
    var body: some View {
        ZStack {
            Color(.lightGray)
                .edgesIgnoringSafeArea(.all)
            VStack {
                Text("I AM Rich")
                    .font(.system(size: 40))
                    .fontWeight(.bold)
                    .foregroundColor(Color.white)
                                
                Image("diamond")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 200, height: 200, alignment: .center)
            }//HStack
        }//ZStack
        .padding()
    }
}

 

 

 

구글 fonts를 사용해서 기본 글씨체에서 벗어나 봅시다 ^_^
https://fonts.google.com/

 

Browse Fonts - Google Fonts

Making the web more beautiful, fast, and open through great typography

fonts.google.com

 

 

저는 Pacifico라는 글꼴을 다운로드 받아서

Fonts 파일에 넣어줬어요 ^_^

 

 

 

 

 

어지러운 글씨체인걸요..?

 

 

 

 

(커스텀 글꼴 설정)

 

글씨체 파일을 추가할때 빌드타겟을 꼭 체크 해줘야 합니다 ^_^

 

 

Text

Text("Chex")
    .font(.custom("Pacifico-Regular", size: 40))
    .bold()
    .foregroundColor(.white)

"Chex"의 텍스트를 추가하고, bold체를 추가, 글씨색인 foregroundColor는 하얀색으로 설정 하였습니다.

uiki의 Label과 비슷한것으로 보입니다.

 

Image

Image("기모즈")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 200, height: 200)
    .clipShape(Circle())
    .overlay(Circle().stroke(Color.white, lineWidth:  5))

간단한 Image를 넣고, 원의 형태와 테두리를 설정한 모습입니다.

 

이미지의 사이즈를 조절하기 위해 resizable을 선언합니다, aspectRatio로 .fit의 사이즈로 이미지를 채웁니다. 

너비와 높이는 200을 하면 원의 이미지가 추가됩니다.

 

이후 테두리 설정을 위해 뷰의 모양을 바꾸어주는 clipShape를 Circle로 선언합니다.

overlay는 뷰 원본의 공간을 기준으로 그 위에 새로운 뷰를 중첩하기 위한 수식어 입니다.

stroke를 이용해 굵기 5인 하얀 테두리를 설정합니다.

 

이 테두리를 설정하기 위해 검색을 하던중, 2가지의 방법이 있더군요.

바로 border과 stroke입니다.

 

border는 View타입의 속성이며 선을 그릴때 뷰의 바깥부터 그려준다고 합니다.

stroke는 Shape타입의 속성이며 선을 그릴때 뷰의 안쪽부터 그려준다고 합니다.

https://nsios.tistory.com/178

 

 

오즈를 보여주는 귀여운 화면을 그렸습니다..

 

 

 

 

 

 

 

 

 

 

 

 

 

 

생각과 감정

요즈음 다시 개발 이놈이랑 권태기가 오는것 같습니다... 강의로 조금 화해를 해보려 합니다.

uikit만 공부하다 Swiftui를 공부하니 흥미가 오르는 기분아닌 기분! 기분전환을 해봤습니다..

완강하고 간단한 개인앱 하나 만들어봐야겠군요~_~

 

앞으로의 계획선언

나태해지지만 않으면 앞으로의 계획은 성공이다..

 

'TIL' 카테고리의 다른 글

TIL_20231226  (0) 2023.12.26
TIL_20231223  (0) 2023.12.23
TIL_20231212  (0) 2023.12.12
TIL_20231126  (0) 2023.11.26
TIL_20231120  (0) 2023.11.20

목요일날 면접이 예정되어있어 다시금 개념을 정리하는 시간을 가졌습니다...

하하 다시보니 또 새롭군군요 ㅋ 대답을 잘할수있을런지...ㅋ

화이또~

 

 

배운점

Struct와 Class와 Enum의 차이를 설명하시오.

Class

단일상속, 참조타입 이기에 데이터를 전달할때 메모리의 위치를 전달함, 주소를 복사하여 이에 존재하는 인스턴스의 위치를 가르킵니다. 참조하는 값이 존재하는 위치를 stack 영역에 참조되는 값을 heap에 저장합니다.

 

Struct

값 타입 이기에 데이터를 전달할때 값을 복사하여 전달, 값이 복사되어 새로운 인스턴스가 생성되고 이 인스턴스가 stack 메모리 영역에 저장, Swift의 대부분 큰 뼈대는 모두 Struct로 구성, 언제사용? -> 참조가 아닌 복사를 원할때

 

Enum

열거형, 유사한 값을 유의미한 이름으로 한곳에 모아 정리, 상속 불가, 열거형 자체가 하나의 프로퍼티, 기존 프로퍼티는 값을 저장하지만 연산 프로퍼티는 특정한 값을 리턴

 

차이 -> Class는 참조타입, Struct와 Enum은 값타입 / Class는 상속가능, Struct와 Enum은 상속 불가

공통점 -> extension이 가능

 

 

Class의 성능을 높일수 있는 방법은?

1. 상속이나 오버라이딩이 필요없는 클래스나 메서드, 프로퍼티에 final을 선언

final이 붙은 메서드나 프로퍼티는 하위 클래스에서 이들을 오버라이딩 할 수 없고, class에 final이 된다면 상속 자체가 불가능 해져 Static Dispatch 방식으로 동작하게 된다.

 

2. 파일 내에서만 접근하는 경우엔 private를 선언.

private로 선언하게 되면 참조 가능한 범위가 private로 선언된 파일 혹은 블록 내에서 가능, 컴파일러는 private가 붙은 프로퍼티에 대해서 오버라이딩 될 수 있는지 판단해 오버라이딩 하는곳에 없다면 final 키워드로 추론.

 

class 앞에 private가 붙으면 클래스 내부의 모든 프로퍼티, 메서드에 private가 붙은것으로 동작

 

 

그래서 final, private, Dispatch가 뭔데..?

 

Dispatch

 

- Static Dispatch

컴파일 시점에 호출할 함수 결정.

( 컴파일 시점? 앱을 동작 시키기 전 개발자가 작성한 코드들이 컴퓨터가 읽을수 있게 만들어서 앱실행을 준비하는 과정)

앱 실행전, 어떤 상황에서 이 함수가 실행될 것인지 결정이 나기 때문에 성능이 좋습니다.

 

- Dtnamic Dispatch

런타임 시점에 호출할 함수를 결정.

( 런타임 시점? 컴파일이 끝난 후 앱을 실행하는 동안 일어나는 과정)

이 경우 하위 클래스가 상위 클래스의 메서드를 호출할 때 해당 메모리 배열을 참조하여 호출하는 함수를 결정하는 과정을 런타임 시점에 결정하여 성능이 떨어짐.

 

참조타입 -> Static Dispatch

값타입 -> Dynamic Dispatch

 

-> Dynamic Dispatch 메커니즘 으로 작동하는 class를 Static Dispatch로 작동하게 한다면 성능이 좋아짐.!

 

 

접근 제어자

: 코드를 작성하는 한 파일에서 다른 파일에 있는 코드에 대한 접근을 명시적으로 작성하게 관리,

module과 source file에 따라 다른 접근을 할 수 있음.

(module은 하나의 프레임워크, 즉 import 키워드로 추가되는것. ex)UIkit, Foundation...

 souece file은 module 안에있는 파일들 xxx.swift)

 

5가지의 접근제어자.

( 접근 제어자가 적용되는 대상 = "Entity")

1. open, public : 프로젝트의 모든 module entity에 접근 가능

2. internal : default 접근 제어자로 entity가 작성된 module에서만 접근 가능

3. file private : entity가 작성된 source file 에서만 접근 가능. 서로 다른 클래스가 같은 파일 안에 file private로 선언된다면 둘은 서로 접근 가능.

4. private : 특정 객체에서만 사용될 수 있도록 하는 가장 제한적인 접근 제어자. file private와 달리 같은 파일 안에 있고 private로 선언되었다면 이 둘은 서로 접근할 수 없음.

 

-> 왜써? : 외부로 부터 데이터를 보호하기 위해, 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해 (= 은닉화)

 

 

 

생각과 감정

말하는 감자에 물을 줍니다... 새싹아 자라나렴....

 

 

 

 

https://im-babycoder.tistory.com/61

https://hcn1519.github.io/articles/2018-01/Swift_AccessControl

 

'TIL' 카테고리의 다른 글

TIL_20231223  (0) 2023.12.23
TIL_20231221  (0) 2023.12.21
TIL_20231126  (0) 2023.11.26
TIL_20231120  (0) 2023.11.20
TIL_20231114  (0) 2023.11.15

 

 

ToDo
✅ 운동은 못함 ㅋ (헬스장 쉼)
✅ 함께자라기 정독

 

 

어제는 과 선배와 동기와 함께 술자리를 가졌슴당 ㅎㅎ

문래는 공장단지 맞는거죠,,? 내부는 상당히 힙하고.. 크리스마스 기분이 물씬 ㅎㅎ

 

신나게 놀고 오늘은 "함께 자라기"를 읽었슴당 ㅎㅎ (카페왔는데 노트북 충전기를 안가져왔다 ㅋ)

 

그리고 토이프로젝트를 깃에 업로드 하였습니다 ^_^

https://github.com/jjwon2149/TodoApp

 

 

 

배운점

 

🐣🐥🐓 자라기

애자일에서 학습은 소프트웨어 개발에 큰 병목 중 하나이다. 그 이유는 일반 프로젝트에서 피드백의 주기가 느려서 결정을 내리고 학습을 한 후 다시 피드백을 받응ㄹ 시기에 이전에 내린 결정에 대한 이유를 기억하기 어렵다.

하지만 애자일 프로젝트에서는 당장 한 행동에 대한 피드백을 10분, 한시간, 하루 주기로 빠르고 지속적으로 받아 다음 주기에 교정할 수 있다.

피드백을 짧은 주기로 얻는 것, 실수를 교정할 기회가 있는 것이 학습에 중요한 요소이다.

실력이 좋은 사람은 당시에 어떤 결정을 어떠한 이유로 내렸는지 자세히 기록하고 나중에 다시 확인하여 피드백을 반드시 얻는다.

 

  1. 자신이 이미 가지고 있는 것들을 잘 활용하라
    • 새로운 것을 유입하기보다 이미 가지고 있는 것을 연결하여 시너지 효과가 나게 한다.
    • 새로운 것은 이미 가지고 있는 것과 연결하도록 해라
  2. 외부 물질을 체화하라
    • 하지만 내부 순환만 하면 수렴할 위험이 있기 때문에 외부 자극을 받으면 좋다.
    • 하지만 외부 자극을 빨리 자기화 해야 한다.
  3. 자신을 개선하는 프로세스에 대해 생각해 보라
    • A를 돌아보는 회고/반성 활동을 주기적으로 해라.
    • 나를 개선하는 과정을 어떻게 개선할지 고민해라.
  4. 피드백을 자주 받아라
    • 사이클 주기를 짧게 두어서 작은 실험을 해 순환율을 높여라.
    • 일찍, 자주 실패해라. 실패에서 학습하라
  5. 자신의 능력을 높여주는 도구와 환경을 점진적으로 만들어라.
    • 완벽한 환경에서 시작하기 보다 점진적으로 자신의 환경을 개선시켜라.
    • 완벽한 환경은 어느날 갖추어지기는 어렵다.

 

생각과 감정

함께자라기는 저를 되돌아볼수 있는 시간을 주는것 같습니다 ^_^ 한번 정독한 후 두번째 정독이라 조금더 이해가 빠르고 와닿습니담ㅁ..다디...

 

저번주 평일에 머리를 싸맨 TodoApp 그냥 기본 라이브러리 사용하면 되는걸 구지비 커스텀을 해서 ㅎㅎ,,, 그래도 유튜버가 친절하게 알려주더군요 ㅎㅎ 다음에 또 할 진 모르겠지만 좋은 경험이였습니다...

 

앞으로의 계획선언

"꾸준히 자기계발에 시간을 쏟으면 그것이 1년, 2년 뒤에 성장해서 돌아온다. 지식이나 능력은 복리로 이자가 붙는다." 

꾸준히 자기계발에 시간을 쏟아 보겠슴담,,,,다,,,디...

 

'TIL' 카테고리의 다른 글

TIL_20231221  (0) 2023.12.21
TIL_20231212  (0) 2023.12.12
TIL_20231120  (0) 2023.11.20
TIL_20231114  (0) 2023.11.15
TIL_20231113  (0) 2023.11.13

+ Recent posts