티스토리 뷰

iOS13+ 사용가능

과거엔 Today Extension 으로 존재했다. (iOS 12까지만 사용가능) - 새롭게 추가 X , 엑스코드에서 사라짐

 

업데이트 기능

iOS 16 → 잠금화면에 추가 가능

iOS 17 → MacDesktop, iPad잠금화면, StandBy, Watch Smart Stack ...
                containerBackground(.fill.tertiary, for: .widget) : 잠금화면에서 위젯 띄울 때 컬러 자연스럽게 변화되는 기능

 

위젯 특징

  • 업데이트 주기가 불명확하다. 하루에 업데이트 40~70번 제한 (1시간마다 업데이트하겠다고 선택해도 대략 한 시간임)
    데이터 변화 시 강제로 위젯을 업데이트하는 방법이 존재하긴 함(아래 참고)
  • 메모리 제한. 30MB
  • .systemSmall, .systemMedium, . systemLarge 사이즈 선택 가능
  • small 사이즈는 버튼 제약이 있음

Widget Configuration

Static - 위젯을 꾹 눌렀을 때 Edit Widget 불가능

Intent - 위젯을 꾹 눌렀을 때 Edit Widget 가능

체크 시 Intent로 만들어진다

 

 

구성

Provider (위젯 디스플레이 업데이트 시기를 WidgetKit에게 알려주기 위한 용도)

Entry

EntryView

Widget

 

AppGroup

위젯도 또 하나의 타겟이기 때문에 데이터를 같이 쓰고 싶다면, 다른 타겟에 대해 데이터를 공유해야한다.

ex) 앱과 위젯에서 같은 키로 UserDefault를 저장해도 저장 공간이 달라서 공유가 안 됨 → Optional Shared

앱과 위젯의 App Groups를 동일하게 설정

 

✔️ UserDefaults 의 경우

extension UserDefaults {
    static var groupShared: UserDefaults {
        let appGroupID = "group.com.dailydrops"    // 만든 앱 그룹
        return UserDefaults(suiteName: appGroupID)!
    }
}
UserDefaults.groupShared.set("", forKey: "key")
UserDefaults.groupShared.string(forKey: "key")

 

✔️ Realm 공유할 경우

// MARK: Migration
let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.dailydrops") // 만든 앱 그룹
let realmURL = containerURL?.appendingPathComponent("default.realm")
if FileManager.default.fileExists(atPath: defaultURL.path) {
    do {
        _ = try FileManager.default.replaceItemAt(realmURL!, withItemAt: defaultURL)
        configuration = Realm.Configuration(fileURL: realmURL, schemaVersion: 1)
    } catch {
       print("Error: \(error)")
    }
} else {
    configuration = Realm.Configuration(fileURL: realmURL, schemaVersion: 1)
}
Realm.Configuration.defaultConfiguration = configuration

기존 Container에 저장되어있는 데이터들을 옮겨야해서 Migration 코드 필요

 

private var realm: Realm {
    let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.dailydrops") // 만든 앱 그룹
    let realmURL = containerURL?.appendingPathComponent("default.realm")
    let config = Realm.Configuration(fileURL: realmURL, schemaVersion: 1)
    return try! Realm(configuration: config)
}

private let realm = try! Realm()

으로 사용했던 것을 위에 코드로 변경해서 공유할 수 있는 Container에 저장하도록 변경

Target Membership 체크해줘야 위젯에서도, 내 앱에서도 접근 가능하다.

 

 

데이터 변화 시 Widget도 업데이트하기

import Foundation
import WidgetKit

protocol WidgetUpdate { }

extension WidgetUpdate {
    func widgetUpdate() {
        WidgetCenter.shared.reloadTimelines(ofKind: "WaterWidget") // WidgetID
    }
}

Widget reload 하는 메서드를 가지고 있는 protocol 생성하여

업데이트를 하고 싶은 곳에 protocol을 채택하여 widgetUpdate() 메서드를 실행해준다

(그냥 업데이트하고 싶은 곳에서 WidgetCenter.shared.reloadTimelines(ofKind: "WaterWidget") 해주면 되지만 WidgetKit을 import 해야해서 protocol로 분리)

(WidgetID는 Widget struct에 kind 상수값)

 

물 섭취 시 realm 데이터 저장 -> 데이터 공유 -> Widget Reload

댓글
최근에 올라온 글
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함