Home > AI > IOS > SwiftUI >

projectedValue

The projectedValue is the property accessed with the $ operator.

Example: This code is ask the permission for Speech Recognition and show the status on UI in real time.

For projectValue, you can access that with $, as stated in description. You don’t need to specify Binding.

import SwiftUI
import Speech



struct ContentView: View {
        
//    @Status var status: SFSpeechRecognizerAuthorizationStatus // method 1, not working
//    @ObservedObject var manager = SpeechAuthManager.shared // method 2, working and simple
    @SpeechAuthStatus var status // method 3, working and fancy
    
    var body: some View {
        VStack {
            
            Text(status.description) // wrappedValue
            
            Text($status.description) // projectedValue
        
        }
        .background(Color.blue)
        .onTapGesture {
            SpeechAuthManager.shared.requestSpeechRecognitionGrant()
        }
        
    } // end body
}



extension SFSpeechRecognizerAuthorizationStatus: CustomStringConvertible {
    public var description: String {
        return ("\(rawValue)") // because rawValue is not String, cannot used in Text
    }
}


class SpeechAuthManager: ObservableObject {
    // singleton
    static let shared = SpeechAuthManager()
    
    
    // status
    @Published var authStatus: SFSpeechRecognizerAuthorizationStatus = SFSpeechRecognizer.authorizationStatus()
    
    
    // request
    func requestSpeechRecognitionGrant() {

        SFSpeechRecognizer.requestAuthorization { authStatus in
            if self.authStatus != authStatus {
                DispatchQueue.main.async {
                    self.authStatus = authStatus
                }
            }
        }
    }
}



// monitor status
@propertyWrapper public struct SpeechAuthStatus: DynamicProperty {
    @ObservedObject var manager = SpeechAuthManager.shared

    let trueValues: Set<SFSpeechRecognizerAuthorizationStatus>

    public init(trueValues: Set<SFSpeechRecognizerAuthorizationStatus> = [.authorized]) {
        self.trueValues = trueValues
    }
    
    public var wrappedValue: SFSpeechRecognizerAuthorizationStatus {
        SpeechAuthManager.shared.authStatus
    }

    public var projectedValue: Bool {
        self.trueValues.contains(SpeechAuthManager.shared.authStatus)
    }
}

Leave a Reply