簡體   English   中英

使用 SwiftUI 和組合根據授權狀態有條件地顯示視圖?

[英]Using SwiftUI and Combine to conditionally display a view based on authorization status?

我正在構建一個 UI,在該視圖中,我想根據 HealthKit 是否已被授權顯示“啟用”按鈕或綠色復選標記。 我還希望視圖具有反應性,以便一旦您授權 HealthKit,視圖就會動態地從按鈕變為復選標記,但我不知道如何正確地進行這兩種通信以及使用哪個屬性包裝器:

struct SetUpWatchView: View {

    let healthKitAuthManager = HealthKitAuthManager()
@ViewBuilder
    var body: some View {
            VStack(alignment: .leading) {
                HStack {
                     Image(systemName: "heart.circle.fill")
                     .foregroundColor(.red)
                      .font(.system(size: 56.0, weight: .bold))
                      .frame(width: 65, height: 65)
                    VStack(alignment: .leading) {
                        Text("Health Integration")
                            .fontWeight(.bold)
                        Text("Enable in Order to Track your Speed, Distance, and Heart Rate.")
                    }
                    Spacer()
                    if healthKitAuthManager.healthKitIsAuthorized {
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundColor(.green)
                            .font(.system(size: 30.0, weight: .bold))
                             .padding(.horizontal)
                    } else {
                        Button(action: {
                            healthKitAuthManager.authorizeHealthKit()
                        }) {
                            Text("ENABLE")
                                .fontWeight(.bold)
                                .foregroundColor(Color.black)
                        }
                        .padding(.horizontal)
                    }
                }
                .padding([.leading, .bottom])
            }.onAppear {
                healthKitAuthManager.checkWhetherHealthKitDatAvailableAndIfAuthorized()
            }
        }
    }
}



class HealthKitAuthManager: ObservableObject {
    
    let healthStore = HKHealthStore()
    
    @Published var healthKitIsAuthorized = false
    
     public func checkWhetherHealthKitDatAvailableAndIfAuthorized()  {
        
        if HKHealthStore.isHealthDataAvailable() {
            
            let authorizationStatus = healthStore.authorizationStatus(for: HKSampleType.workoutType())
            switch authorizationStatus {
            case .sharingAuthorized:
                
                healthKitIsAuthorized = true
                
            case .sharingDenied: ()
             healthKitIsAuthorized = false
            default:()
              healthKitIsAuthorized = false
            }
            
        }
        else {
            healthKitIsAuthorized = false 
        }
    }

    public func authorizeHealthKit() {

        let healthKitTypesToWrite: Set<HKSampleType> = [
            HKObjectType.workoutType(),
            HKSeriesType.workoutRoute(),
            HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
            HKObjectType.quantityType(forIdentifier: .heartRate)!,
            HKObjectType.quantityType(forIdentifier: .restingHeartRate)!,
            HKObjectType.quantityType(forIdentifier: .bodyMass)!,
            HKObjectType.quantityType(forIdentifier: .vo2Max)!,
            HKObjectType.quantityType(forIdentifier: .stepCount)!,
            HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning)!]

        let healthKitTypesToRead: Set<HKObjectType> = [
            HKObjectType.workoutType(),
            HKSeriesType.workoutRoute(),
            HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
            HKObjectType.quantityType(forIdentifier: .heartRate)!,
            HKObjectType.quantityType(forIdentifier: .restingHeartRate)!,
            HKObjectType.characteristicType(forIdentifier: .dateOfBirth)!,
            HKObjectType.quantityType(forIdentifier: .bodyMass)!,
            HKObjectType.quantityType(forIdentifier: .vo2Max)!,
            HKObjectType.quantityType(forIdentifier: .stepCount)!,
            HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning)!]

        let authorizationStatus = HKHealthStore().authorizationStatus(for: HKSampleType.workoutType())

        switch authorizationStatus {

        case .sharingAuthorized:

            print("Sharing Authorized")
            healthKitIsAuthorized = true

        case .sharingDenied: print("sharing denied")

        //Success does NOT necessarily mean we are authorized, only that the request was successfully delivered.  Also if a user chooses not to authorize, if you call .requestAuthorization again you won't get the action sheet
        HKHealthStore().requestAuthorization(toShare: healthKitTypesToWrite, read: healthKitTypesToRead) { (success, error) in
            if !success {
                print("failed HealthKit Authorization from iPhone SetUpWatchVC \(String(describing: error?.localizedDescription))")
            }

            print("Successful HealthKit Authorization from iPhone")
            }

        default: print("not determined")

        HKHealthStore().requestAuthorization(toShare: healthKitTypesToWrite, read: healthKitTypesToRead) { (success, error) in
            if !success {
                print("failed HealthKit Authorization from iPhone SetUpWatchVC \(String(describing: error?.localizedDescription))")
            }

            print("Successful HealthKit Authorization from iPhone SetUpWatchVC")

            }

        }



    }

}

嘗試添加@ObservedObject var healthKitAuthManager = HealthKitAuthManager()而不是let healthKitAuthManager = HealthKitAuthManager() 這樣@Published變量將觸發新的視圖渲染。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM