Sensorkit中只有didFetchResult deligate方法没有被调用

问题描述 投票:0回答:1
func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool {
    print("sensorReader(_:fetching:didFetchResult:) method called")

    guard let ambientSample = result.sample as? SRAmbientLightSample else {
        print("Unexpected sample type: \(type(of: result.sample))")
        return true
    }

    let luxValue = ambientSample.lux.value
    let timestamp = Date(timeIntervalSinceReferenceDate: result.timestamp.rawValue)

    print("Ambient light sample: lux value = \(luxValue) lux, timestamp = \(timestamp)")

    // Check if the data is between 24 hours and 72 hours old
    let twentyFourHoursAgo = Date().addingTimeInterval(-24 * 60 * 60)
    let seventyTwoHoursAgo = Date().addingTimeInterval(-72 * 60 * 60)

    if timestamp >= seventyTwoHoursAgo && timestamp <= twentyFourHoursAgo {
        DispatchQueue.main.async {
            let dataPoint = AmbientLightDataPoint(timestamp: timestamp, lux: Float(luxValue))
            self.ambientLightData.append(dataPoint)
            print("Added ambient light data: \(luxValue) lux, Timestamp: \(timestamp)")
        }
        self.displayAmbientLightData(sample: ambientSample)
    } else {
        print("Data ignored as it is outside the 24 to 72-hour window: \(luxValue) lux, Timestamp: \(timestamp)")
    }

    return true // Indicates no further processing is needed
}

这是一个关于实现SensorKit Deligate的问题。目前您可以添加具有所有权限的条目来获取设备信息。

但是为什么不仅仅是didFetchResult这个获取照度值的值被deligate方法调用了。其他deligate方法调用得很好(例如设备调用相关方法,didCompleteFetch等)请帮忙

SensorKit的权限正常接收,可以调用数据,包括其他Deligate方法和权限设置。目前检查了实际设备内可以共享的光照值,但没有调用代码中调用 Deligate 光照值的方法。

ios swift delegates
1个回答
0
投票
import Foundation

导入传感器套件 导入 UIKit

最终类 SensorKitManager:NSObject、ObservableObject、SRSensorReaderDelegate {

static let shared = SensorKitManager()

private let ambientReader = SRSensorReader(sensor: .ambientLightSensor)

private var availableDevices: [SRDevice] = []

@Published var ambientLightData: [AmbientLightDataPoint] = []

var isFetching = false
var isRecordingAmbientLight = false

private override init() {
    super.init()
    setupReaders()
    checkAndRequestAuthorization()
}

private func setupReaders() {
    ambientReader.delegate = self
}

// MARK: - 권한 설정

func requestAuthorization() {
    SRSensorReader.requestAuthorization(sensors: [.ambientLightSensor]) { [weak self] error in
        DispatchQueue.main.async {
            guard let self = self else {
                print("권한 요청 중단")
                return
            }
            
            if let error = error {
                print("권한 요청 실패: \(error.localizedDescription)")
                if (error as NSError).code == SRError.promptDeclined.rawValue {
                    print("사용자 권한 거부")
                }
            } else {
                print("권한 요청 성공")
                self.startRecordingAmbientLightData()
            }
        }
    }
}

func checkAndRequestAuthorization() {
    let status = ambientReader.authorizationStatus
    
    switch status {
    case .authorized:
        print("조도 센서 접근 허용됨")
        startRecordingAmbientLightData()
        
    case .notDetermined:
        print("조도 센서 접근 미결정, 권한 요청 시작")
        requestAuthorization()
    case .denied:
        print("조도 센서에 대한 접근 거부 또는 제한됨")
        // 필요한 경우 사용자에게 설정에서 권한을 변경하도록 안내하는 로직
    @unknown default:
        print("알 수 없는 권한 상태입니다.")
    }
}

// MARK: - 조도 값 로직

func startRecordingAmbientLightData() {
    guard !isRecordingAmbientLight else {
        print("이미 조도 데이터 기록 중입니다.")
        return
    }
    
    print("조도 데이터 기록 시작")
    isRecordingAmbientLight = true
    ambientReader.startRecording()
    fetchAmbientDeviceData()
    fetchAmbientLightData()
    triggerDummyFetchResult()
}

private func fetchAmbientDeviceData() {
    print("디바이스 정보 페치 시작")
    let fetchRequest = SRFetchRequest()
    
    // 48시간 전부터 24시간 전까지의 데이터 요청 (대기 기간을 벗어난 데이터)
    let fromDate = Date().addingTimeInterval(-72 * 60 * 60)
    let toDate = Date().addingTimeInterval(-24 * 60 * 60)
    
    fetchRequest.from = SRAbsoluteTime(fromDate.timeIntervalSinceReferenceDate)
    fetchRequest.to = SRAbsoluteTime(toDate.timeIntervalSinceReferenceDate)
    
    if availableDevices.isEmpty {
        print("디바이스 없음")
        ambientReader.fetchDevices()
    } else {
        for device in availableDevices {
            print("데이터 페치 시작 (디바이스: \(device))")
            fetchRequest.device = device
            ambientReader.fetch(fetchRequest)
            print("페치 요청 보냄 (디바이스: \(device))")
        }
    }
}

func fetchAmbientLightData() {
    guard !isFetching else {
        print("이미 페치 중입니다.")
        return
    }
    
    isFetching = true
    
    let fetchRequest = SRFetchRequest()
    let now = Date()
    let fromDate = now.addingTimeInterval(-72 * 24 * 60 * 60)
    let toDate = now.addingTimeInterval(-24 * 60 * 60) // 24시간 전
    fetchRequest.from = SRAbsoluteTime(fromDate.timeIntervalSinceReferenceDate)
    fetchRequest.to = SRAbsoluteTime(toDate.timeIntervalSinceReferenceDate)
    fetchRequest.device = SRDevice.current
    
    ambientReader.fetch(fetchRequest)
}

private func displayAmbientLightData(sample: SRAmbientLightSample) {
    print("조도: \(sample.lux.value) lux")
    
    // ambientLightData 배열의 전체 내용을 추가로 출력
    print("현재 ambientLightData 내용:")
    for data in ambientLightData {
        print("Timestamp: \(data.timestamp), Lux: \(data.lux)")
    }
}

// MARK: - Dummy Test

func triggerDummyFetchResult() {
    print("더미 데이터로 didFetchResult 호출 테스트")
    
    // 실제로 데이터가 패치될 수 있는지 테스트할 수 있는 요청을 만들고 호출
    fetchAmbientLightData()  // 실 데이터를 통해 패치 시도
}



// MARK: - SRSensorReaderDelegate 메서드

func sensorReader(_ reader: SRSensorReader, didFetch devices: [SRDevice]) {
    print("장치 페치 : \(devices.count)개")
    
    availableDevices = devices
    
    for device in devices {
        print("페치된 장치: \(device)")
    }
    
    if !devices.isEmpty {
        fetchAmbientDeviceData()
    }
}

func sensorReader(_ reader: SRSensorReader, didCompleteFetch fetchRequest: SRFetchRequest) {
    print("데이터 페치 완료")
    isFetching = false
    
    // 현재 시간 기준으로 24시간 전과 72시간 전 시간 계산
    let now = Date()
    let twentyFourHoursAgo = now.addingTimeInterval(-24 * 60 * 60)
    let seventyTwoHoursAgo = now.addingTimeInterval(-72 * 60 * 60)
    
    // 페치된 데이터 중 24시간에서 72시간 사이의 데이터만 필터링
    let filteredData = ambientLightData.filter { dataPoint in
        dataPoint.timestamp >= seventyTwoHoursAgo && dataPoint.timestamp <= twentyFourHoursAgo
    }
    
    if filteredData.isEmpty {
        print("24시간에서 72시간 사이의 조도 데이터가 없습니다.")
        // 필요한 경우 기본 데이터 추가
        DispatchQueue.main.async {
            let defaultTimestamp = twentyFourHoursAgo
            let dataPoint = AmbientLightDataPoint(timestamp: defaultTimestamp, lux: 10.0)
            self.ambientLightData.append(dataPoint)
            print("ambientLightData에 추가된 기본 조도 값: 0.0 lux, Timestamp: \(defaultTimestamp)")
        }
    } else {
        // 필터링된 데이터로 ambientLightData 업데이트
        DispatchQueue.main.async {
            self.ambientLightData = filteredData
            print("24시간에서 72시간 사이의 조도 데이터 \(filteredData.count)개를 추가했습니다.")
            // 데이터 로깅
            for dataPoint in filteredData {
                print("추가된 조도 값: \(dataPoint.lux) lux, Timestamp: \(dataPoint.timestamp)")
            }
        }
    }
}

func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool {
    print("sensorReader(_:fetching:didFetchResult:) 메서드 호출됨")
    
    if let ambientSample = result.sample as? SRAmbientLightSample {
        print("Lux value: \(ambientSample.lux.value)")
        
        // 추가 로직: 중복된 데이터가 있는지 확인하고 없을 때만 추가
        let timestamp = Date(timeIntervalSinceReferenceDate: result.timestamp.rawValue)
        if !ambientLightData.contains(where: { $0.timestamp == timestamp }) {
            let dataPoint = AmbientLightDataPoint(timestamp: timestamp, lux: Float(ambientSample.lux.value))
            ambientLightData.append(dataPoint)
            print("ambientLightData에 추가된 조도 값: \(ambientSample.lux.value) lux, Timestamp: \(timestamp)")
        } else {
            print("중복된 데이터이므로 추가하지 않음: Timestamp: \(timestamp)")
        }
        
        // 데이터 출력
        self.displayAmbientLightData(sample: ambientSample)
    }
    
    return true
}


func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, failedWithError error: Error) {
    print("페치 요청 실패: \(error.localizedDescription)")
}

func sensorReaderWillStartRecording(_ reader: SRSensorReader) {
    print("레코딩 시작됨")
}

func sensorReaderDidStopRecording(_ reader: SRSensorReader) {
    print("조도 데이터 기록 중단됨")
    isRecordingAmbientLight = false
}

func sensorReader(_ reader: SRSensorReader, startRecordingFailedWithError error: Error) {
    print("레코딩 시작 실패: \(error.localizedDescription)")
}

这是目前 SensorKit 的完整代码。只有 didFetchResult deligate 方法没有被调用。感谢您尝试提供帮助

© www.soinside.com 2019 - 2024. All rights reserved.