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 光照值的方法。
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 方法没有被调用。感谢您尝试提供帮助