Возможность доступа к environmentObject не подклассами View в SwiftUI - PullRequest
0 голосов
/ 18 апреля 2020

Я понимаю, что EnvironmentObjects предназначены для обмена данными между представлениями. Мне любопытно узнать, могут ли другие подклассы, не относящиеся к View, получить доступ к EnvironmentObjects и обновить их. Если да, то нарушаем ли мы здесь какой-либо архитектурный паттерн?
Какой должен быть наш подход, если нам нужен доступ к объектам EnvironmentObject в подклассах без просмотра

Edit-I

Я использую AVFoundation для получения видеокадры. После получения фреймов я пытаюсь обновить environmentObject, чтобы все виды могли получить доступ к фрейму. Ниже приведен код:

class Coordinator {

    let delegate = VideoDelegate()
    let controller: CameraController!

    init(){

        controller = CameraController(delegate)
    }
}

final class VideoDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate{
    @EnvironmentObject var frame: CIImageFrame

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

        if let cvImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {

            self.frame.image = CIImage(cvImageBuffer: cvImageBuffer)

        } else {

            //Log message
            print("CMSampleBuffer to CIImage conversion error")
        }
    }
}



//Wrap CIImage to make it EnvironmentObject
final class CIImageFrame: ObservableObject {
   @Published var image = CIImage()
}

Объект координатора создается в одном из представлений

1 Ответ

0 голосов
/ 18 апреля 2020

EnvironmentObject - это просто механизм для внедрения экземпляра ссылочного типа, подтверждающего протокол ObservableObject, в иерархию представлений SwiftUI и обновления такого представления, если соответствующие свойства изменились, просто наблюдая за соответствующими издателями. Но это просто обычный экземпляр ссылочного типа, вы можете передавать его здесь и там таким же образом, как вы передаете любой другой экземпляр ссылочного типа и работать с ним (свойствами, функциями), как с любым другим экземпляром ссылочного типа.

Нет волхвов c.

Обновление: сейчас для кода

Вам не нужно использовать оболочку @EnvironmentObject в своем делегате для представлений, вместо этого используйте следующее (неуклюжий, поскольку ваш код сокращен)

class Coordinator {
    let owner: _Owner_Type_     // << here is owner view of coordinator
    let delegate: VideoDelegate
    let controller: CameraController!

    init(owner: _Owner_Type_){
        self.owner = owner

        // owner is view which has @EnvironmentObject property, 
        // so use it here to pass into VideoDelegate
        delegate = VideoDelegate(frame: owner.frame)

        controller = CameraController(delegate)
    }
}

final class VideoDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate{
    private var frame: CIImageFrame // just reference member

    // now your delegate has reference to the same instance as environment
    // object in view
    init(frame: CIImageFrame) {
       self.frame = frame
    }
    ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...