Level : WORDPRESS BOOK LINKEDIN PATENT Send Mail 동냥하기 hajunho.com

userDefault 활용

XaaS/FireBase / / 2019. 1. 16. 23:52
반응형

[이 문서는 계속 업데이트 됩니다.]

native 장치, 외부 라이브러리, 오픈소스, 쓰레드 작업 등등 은 userDefaut 가 좋다. 512KB 를 넘지 않는 선에서 써야 한다.

그건 10만자 라고 생각하면 기억하기 쉽고, 각각의 디바이스 이고 개별 저장소임을 감안할 때 앱에서 느낌은 거의 무한한 공간으로 느껴진다. 

  1. ASCII 문자 (영문 알파벳, 숫자, 기본 구두점): 1 바이트
  2. 대부분의 유럽 언어, 중동 언어, 아프리카 언어의 문자: 2 바이트
  3. 한글, 한자, 일본어 등 아시아 언어의 문자: 3 바이트
  4. 이모지 및 특수 기호: 4 바이트

512KB는 512 * 1024 = 524,288 바이트입니다.

만약 모든 문자가 ASCII라면, 최대 524,288 문자를 저장할 수 있습니다. 524,288 바이트 / 1 바이트 = 524,288 문자

그러나 모든 문자가 한글이라면, 최대 174,762 문자를 저장할 수 있습니다. 524,288 바이트 / 3 바이트 ≈ 174,762 문자 (소수점 이하 버림)

실제 상황에서는 다양한 문자가 혼합되어 사용되므로, 저장할 수 있는 정확한 문자 수는 문자의 구성에 따라 달라집니다. 대략적으로는 다음과 같이 추정할 수 있습니다:

  • 주로 ASCII 문자를 사용하는 경우: 약 500,000자
  • 주로 유럽어, 중동어, 아프리카어 문자를 사용하는 경우: 약 250,000자
  • 주로 한글, 한자, 일본어 등을 사용하는 경우: 약 170,000자
  • 이모지와 특수 기호를 많이 사용하는 경우: 약 130,000자

따라서 512KB는 상당히 많은 양의 텍스트 데이터를 저장할 수 있지만, 데이터의 성격에 따라 실제로 저장할 수 있는 문자 수는 크게 달라질 수 있습니다.

대림산업 이제는 바뀐 DL E&C 에서 담당했던 before Service 앱에서 13만건 이상 한 방에 싱크해야 하는 상황에서의 오프라인 싱크 앱 경험으로 sqlite 는 뻑난다. 파일 생성 역시나 안정적이지 못했다. UserDefault야 이미 13만 건 * 데이터 필드 개수 * 각 필드별 문자수 계산 하면 한계를 아득히 넘어 버리는 수치이기에 쓸 수 있지도 않았다. sql 에 저장하면 읽는데도 어마어마한 시간이 걸렸었다. 해결 방법은 시간적 공간적 분할 외엔 없었다. 시간은 CPU, 공간은 메모리... 결국... 내가 썼던 책 그대로의 내용이다.(세속적으로 말하면 기본기는 알려주나 경험적 지식은 스스로 터득하라는 것) 왜냐면, 시간이 지나서 안 사실이지만. 타이틀만 중요시하며 딱히 중요하지도 않은 지식을 공유하며 그것이 아닌 그 누군가에게도 고마워하지 않는 세상이라는 것을 알아버렸지 때문일까. 혹은, 그렇게 된 세상, 문화를 바로 잡기 위해서 필드의 지식은 필드에 그대로 남겨두고 싶어서일까. 그래도 공부 하고자 하는 이들을 위한 발자취는 남겨둔다. 덜 고생하시라고.

 

UserDefaults는 iOS 앱에서 간단한 데이터를 저장하고 검색하는 데 사용되는 편리한 메커니즘입니다. 그러나 모든 상황에 적합한 것은 아닙니다. UserDefaults를 사용하여 데이터를 저장하고 전송하는 것의 장단점과 제한 사항은 다음과 같습니다.

장점:

  1. 간편성: UserDefaults는 key-value 쌍을 사용하여 데이터를 저장하고 검색하는 간단한 방법을 제공합니다.
  2. 빠른 액세스: UserDefaults에 저장된 데이터는 빠르게 액세스할 수 있습니다.
  3. 영구 저장: UserDefaults에 저장된 데이터는 앱이 종료되거나 기기가 재부팅되어도 유지됩니다.

단점:

  1. 제한된 데이터 유형: UserDefaults는 주로 기본 데이터 유형(String, Int, Bool 등)과 일부 컬렉션 유형(Array, Dictionary)만 지원합니다. 사용자 정의 객체를 저장하려면 Codable 프로토콜을 준수해야 합니다.
  2. 제한된 저장 공간: UserDefaults는 대량의 데이터를 저장하기에 적합하지 않습니다. Apple은 UserDefaults에 저장되는 데이터를 약 512KB로 제한할 것을 권장합니다.
  3. 보안 고려 사항: UserDefaults에 저장된 데이터는 암호화되지 않으므로 중요한 정보를 저장하는 데 적합하지 않습니다.

제한 사항 (Limits):

  1. 데이터 크기: Apple은 UserDefaults에 저장되는 데이터를 약 512KB로 제한할 것을 권장합니다. 이 제한을 초과하면 앱의 성능에 영향을 줄 수 있습니다.
  2. 데이터 유형: UserDefaults는 주로 기본 데이터 유형과 일부 컬렉션 유형만 지원합니다. 사용자 정의 객체를 저장하려면 추가 작업이 필요합니다.

외부 라이브러리 및 API와의 상호 작용:

  • 외부 라이브러리나 API에서 받은 데이터를 UserDefaults에 직접 저장하는 것은 일반적으로 권장되지 않습니다. 대신, 데이터를 적절한 데이터 모델로 변환한 후 필요한 경우 UserDefaults에 저장하는 것이 좋습니다.
  • 이미지나 비디오와 같은 큰 데이터는 UserDefaults 대신 파일 시스템이나 Core Data와 같은 다른 저장 메커니즘을 사용하는 것이 좋습니다.

요약하면, UserDefaults는 간단한 데이터를 저장하고 전송하는 데 유용하지만, 대량의 데이터나 복잡한 객체를 다룰 때는 한계가 있습니다. 데이터의 유형과 크기에 따라 적절한 저장 메커니즘을 선택하는 것이 중요합니다.

 

@State private var udfirstArg = UserDefaults.standard.string(forKey: "CameraViewfirstArg")

var udfirstArg = UserDefaults.standard.string(forKey: "CameraViewfirstArg")

UserDefaults.standard.set(self.firstArg, forKey: "CameraViewfirstArg")

//            let savingLocation = "gs://" + (self.udfirstArg ?? "") + "/" + "230830.jpeg"

 

 

func makeUIViewController(context: Context) -> HjHCameraViewController {

        print("func makeUIViewController(context: Context) -> HjHCameraViewController {")

        UserDefaults.standard.set(self.firstArg, forKey: "CameraViewfirstArg")

        UserDefaults.standard.set(self.secondArg, forKey: "CameraViewSecondArg")

        UserDefaults.standard.set(self.thirdArg, forKey: "CameraViewThirdArg")

        

        let vc = HjHCameraViewController()

        vc.modalPresentationStyle = .fullScreen

        return vc

    }

 

 

 

 

//

//  HjhCameraView.swift

//  App

//

//  Created by Junho HA on 2023-04-30.

//

 

import SwiftUI

 

 

struct HjhCameraView: UIViewControllerRepresentable {

    

    let firstArg : String

    let secondArg : String //let secondarg = $item.businessNumber

    let thirdArg : String //처방월_년

    

    typealias UIViewControllerType = HjHCameraViewController

    

    func makeUIViewController(context: Context) -> HjHCameraViewController {

        print("func makeUIViewController(context: Context) -> HjHCameraViewController {")

        UserDefaults.standard.set(self.firstArg, forKey: "CameraViewfirstArg")

        UserDefaults.standard.set(self.secondArg, forKey: "CameraViewSecondArg")

        UserDefaults.standard.set(self.thirdArg, forKey: "CameraViewThirdArg")

        

        let vc = HjHCameraViewController()

        vc.modalPresentationStyle = .fullScreen

        return vc

    }

    

    func updateUIViewController(_ uiViewController: HjHCameraViewController, context: Context) {

        // Updates the state of the specified view controller with new information from SwiftUI.

        

    }

    

}

 

 

 

            Section {

                Toggle(isOn: $continuousTakePicture) {

                    Text("연속 촬영")

                }

                Button(action: {

                    print("EDIEDI")

                    let dateFormatter = DateFormatter()

                    dateFormatter.dateFormat = "MM_yyyy" // "MMMM yyyy" will give you the full month name and the year

                    

                    if let window = UIApplication.shared.windows.first {

                        let subject = "\($item.summary.wrappedValue)_\($item.owner_id.wrappedValue)"

                        let body = "_\($item.owner_id.wrappedValue)_거래처명:\($item.summary.wrappedValue)"

                        //                        let thirdarg = dateFormatter.string(from: date)

                        let thirdarg : String = String(month) + "_" + String(year)

                        print("hjhdate : \(dateFormatter.string(from: date))")

                        //                        let secondarg = dateFormatter.string(from: date)

                        let secondarg:String = $item.businessNumber.wrappedValue

                        window.rootViewController = UIHostingController(rootView: HjhCameraView(firstArg: $item.summary.wrappedValue, secondArg: secondarg, thirdArg: thirdarg))

                        window.makeKeyAndVisible()

                    }

                }, label: {

                    HStack {

                        Spacer() // 버튼 내부에서 텍스트를 중앙에 위치시키기 위해 사용

                        Image(systemName: "camera")

                            .imageScale(.large)

                            .foregroundColor(.white) // 아이콘 색상 조정

                        Text("EDI 촬영")

                            .fontWeight(.bold)

                            .foregroundColor(.white) // 텍스트 색상 조정

                        Spacer() // 버튼 내부에서 텍스트를 중앙에 위치시키기 위해 사용

                    }

                    .padding() // 버튼 내부 여백 추가

                    .background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.purple]), startPoint: .leading, endPoint: .trailing)) // 그라디언트 배경 적용

                    .cornerRadius(10) // 모서리 둥글게

                    .shadow(radius: 5) // 그림자 효과 추가

                })

                .frame(maxWidth: .infinity) // 최대 너비 설정

                

                // 서버로 자동 전송" 토글 상태에 따라 조건부 렌더링

                if settingActivated {

                    Button(action: {

                        checkCameraAccess()

                        self.isShowingImagePicker = true

                        //                        self.uploadState = .idle

                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {

                            self.uploadState = .idle

                            // 업로드 성공 후 필요한 UI 초기화 로직을 여기에 추가

                            // 예: 선택된 이미지를 초기화한다거나, 성공 메시지를 표시하는 등

                        }

                        

                    }) {

                        Text("갤러리에서 사진 선택")

                            .frame(maxWidth: .infinity)

                            .padding()

                            .background(LinearGradient(gradient: Gradient(colors: [Color.purple.opacity(0.8), Color.blue.opacity(0.8)]), startPoint: .leading, endPoint: .trailing))

                            .foregroundColor(.white)

                            .cornerRadius(10)

                            .shadow(radius: 5)

                    }

                    .padding(.horizontal)

                    .fullScreenCover(isPresented: $isShowingImagePicker, onDismiss: loadImage) {

                        // ImagePicker 뷰 표시

                        HjhImagePicker(selectedImage: $selectedUIImage)

                    }

                    

                }

            }

            

반응형

'XaaS > FireBase' 카테고리의 다른 글

폐쇄적 환경, 불특정 다수를 위한 firebase storage setting  (0) 2019.01.21
제주도 항공 촬영  (0) 2019.01.19
C의 struct와 Swift 의 struct  (0) 2019.01.19
Practical Swift  (0) 2019.01.14
iOS UI 기초 - Swift UI  (2) 2019.01.03
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기