Я разработал приложение WatchOS, которое записывает голос, пока пользователь спит. Я заметил, что это приложение закрывается через несколько часов. Как я могу это предотвратить? < /P>
ps. Приложение может работать на iPhone пользователя в то же время, что и пользователь Apple Watc, в случае, если приложение, работающее на iPhone >
import SwiftUI
import AVFoundation
import WatchKit
import CryptoKit
class AudioRecorder: NSObject, ObservableObject, AVAudioRecorderDelegate {
@Published var isRecording = false
@Published var recordings: [Recording] = []
private var audioRecorder: AVAudioRecorder?
private var currentRecordingURL: URL?
private var encryptionKey : SymmetricKey = SymmetricKey(size: .bits256)
private var audioBuffer: Data = Data()
private let bufferSizeThreshold = 4096
private var recordingTimer: Timer?
private let recordingChunkDuration: TimeInterval = 10
private let pauseDuration: TimeInterval = 5
private var audioSessionInitialized = false // Flag to track session setup
override init(){
super.init()
recordings = loadRecordings()
encryptionKey = getEncryptionKey()
}
func startRecording() {
setupAudioSession() // Ensure session is set up before recording
let fileManager = FileManager.default
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd_HHmmss"
let recordingName = dateFormatter.string(from: Date()) + ".m4a"
currentRecordingURL = documentsDirectory.appendingPathComponent(recordingName)
let settings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 22050.0,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue
]
do {
audioRecorder = try AVAudioRecorder(url: currentRecordingURL!, settings: settings)
audioRecorder?.delegate = self
// Remove intermittent recording for now to simplify debugging
audioRecorder?.record() // Record continuously instead of in chunks
isRecording = true
print("Started recording to:", currentRecordingURL!) // Debug print
} catch {
print("Error starting recording:", error)
isRecording = false
}
}
private func setupAudioSession() {
do {
let audioSession = AVAudioSession.sharedInstance()
// Specify .record for recording-only
//https://stackoverflow.com/questions/515 ... ith-others
// [.mixWithOthers, .defaultToSpeaker] .defaultToSpeaker is unavailablke in WatchOS:
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers]) //
try audioSession.setActive(true)
print("Audio session activated.")
} catch {
print("Error setting up audio session:", error)
}
}
func stopRecording() {
audioRecorder?.stop()
isRecording = false
currentRecordingURL = nil
audioBuffer = Data()
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
guard flag else { return }
let tempURL = recorder.url
let encryptionEnabled = UserDefaults.standard.bool(forKey: "encryptionEnabled")
do {
if encryptionEnabled {
let data = try Data(contentsOf: tempURL)
let encryptedData = try ChaChaPoly.seal(data, using: encryptionKey).combined
let encryptedFileName = "encrypted_\(tempURL.lastPathComponent)"
let encryptedURL = tempURL.deletingLastPathComponent().appendingPathComponent(encryptedFileName)
try encryptedData.write(to: encryptedURL)
DispatchQueue.main.async {
self.recordings.insert(Recording(url: encryptedURL, createdAt: Date()), at: 0)
}
try FileManager.default.removeItem(at: tempURL)
} else {
DispatchQueue.main.async {
self.recordings.insert(Recording(url: tempURL, createdAt: Date()), at: 0)
}
}
} catch {
print("Failed to process recording:", error)
}
}
func getDecryptedData(from url: URL) throws -> Data? {
let fileData = try Data(contentsOf: url)
if url.lastPathComponent.hasPrefix("encrypted_") {
let sealedBox = try ChaChaPoly.SealedBox(combined: fileData)
let decryptedData = try ChaChaPoly.open(sealedBox, using: encryptionKey)
return decryptedData
} else {
return fileData
}
}
func loadRecordings() -> [Recording] {
let fileManager = FileManager.default
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
do {
let files = try fileManager.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil)
let recordingFiles = files.filter { $0.pathExtension == "m4a" }
return recordingFiles.map { fileURL in
let attributes = try? fileManager.attributesOfItem(atPath: fileURL.path)
let createdAt = attributes?[.creationDate] as? Date ?? Date()
return Recording(url: fileURL, createdAt: createdAt)
}.sorted(by: { $0.createdAt > $1.createdAt })
} catch {
print("Error loading recordings: \(error)")
return []
}
}
func getEncryptionKey() -> SymmetricKey {
let keychainKey = "ziziapps.guardianangel.encryptionKey"
let keychainHelper = KeychainHelper()
if let keyData = keychainHelper.read(key: keychainKey) {
return SymmetricKey(data: keyData)
} else {
// Generate a new key if one doesn't exist, then store it
let newKey = SymmetricKey(size: .bits256)
let keyData = newKey.withUnsafeBytes { Data($0) }
keychainHelper.save(keyData, key: keychainKey)
return newKey
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... eral-hours
Приложение для записи голоса watchos закрывается через несколько часов ⇐ IOS
Программируем под IOS
1740544059
Anonymous
Я разработал приложение WatchOS, которое записывает голос, пока пользователь спит. Я заметил, что это приложение закрывается через несколько часов. Как я могу это предотвратить? < /P>
ps. Приложение может работать на iPhone пользователя в то же время, что и пользователь Apple Watc, в случае, если приложение, работающее на iPhone >
import SwiftUI
import AVFoundation
import WatchKit
import CryptoKit
class AudioRecorder: NSObject, ObservableObject, AVAudioRecorderDelegate {
@Published var isRecording = false
@Published var recordings: [Recording] = []
private var audioRecorder: AVAudioRecorder?
private var currentRecordingURL: URL?
private var encryptionKey : SymmetricKey = SymmetricKey(size: .bits256)
private var audioBuffer: Data = Data()
private let bufferSizeThreshold = 4096
private var recordingTimer: Timer?
private let recordingChunkDuration: TimeInterval = 10
private let pauseDuration: TimeInterval = 5
private var audioSessionInitialized = false // Flag to track session setup
override init(){
super.init()
recordings = loadRecordings()
encryptionKey = getEncryptionKey()
}
func startRecording() {
setupAudioSession() // Ensure session is set up before recording
let fileManager = FileManager.default
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd_HHmmss"
let recordingName = dateFormatter.string(from: Date()) + ".m4a"
currentRecordingURL = documentsDirectory.appendingPathComponent(recordingName)
let settings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 22050.0,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue
]
do {
audioRecorder = try AVAudioRecorder(url: currentRecordingURL!, settings: settings)
audioRecorder?.delegate = self
// Remove intermittent recording for now to simplify debugging
audioRecorder?.record() // Record continuously instead of in chunks
isRecording = true
print("Started recording to:", currentRecordingURL!) // Debug print
} catch {
print("Error starting recording:", error)
isRecording = false
}
}
private func setupAudioSession() {
do {
let audioSession = AVAudioSession.sharedInstance()
// Specify .record for recording-only
//https://stackoverflow.com/questions/51597590/avaudiosession-configuration-to-record-and-play-with-others
// [.mixWithOthers, .defaultToSpeaker] .defaultToSpeaker is unavailablke in WatchOS:
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers]) //
try audioSession.setActive(true)
print("Audio session activated.")
} catch {
print("Error setting up audio session:", error)
}
}
func stopRecording() {
audioRecorder?.stop()
isRecording = false
currentRecordingURL = nil
audioBuffer = Data()
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
guard flag else { return }
let tempURL = recorder.url
let encryptionEnabled = UserDefaults.standard.bool(forKey: "encryptionEnabled")
do {
if encryptionEnabled {
let data = try Data(contentsOf: tempURL)
let encryptedData = try ChaChaPoly.seal(data, using: encryptionKey).combined
let encryptedFileName = "encrypted_\(tempURL.lastPathComponent)"
let encryptedURL = tempURL.deletingLastPathComponent().appendingPathComponent(encryptedFileName)
try encryptedData.write(to: encryptedURL)
DispatchQueue.main.async {
self.recordings.insert(Recording(url: encryptedURL, createdAt: Date()), at: 0)
}
try FileManager.default.removeItem(at: tempURL)
} else {
DispatchQueue.main.async {
self.recordings.insert(Recording(url: tempURL, createdAt: Date()), at: 0)
}
}
} catch {
print("Failed to process recording:", error)
}
}
func getDecryptedData(from url: URL) throws -> Data? {
let fileData = try Data(contentsOf: url)
if url.lastPathComponent.hasPrefix("encrypted_") {
let sealedBox = try ChaChaPoly.SealedBox(combined: fileData)
let decryptedData = try ChaChaPoly.open(sealedBox, using: encryptionKey)
return decryptedData
} else {
return fileData
}
}
func loadRecordings() -> [Recording] {
let fileManager = FileManager.default
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
do {
let files = try fileManager.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil)
let recordingFiles = files.filter { $0.pathExtension == "m4a" }
return recordingFiles.map { fileURL in
let attributes = try? fileManager.attributesOfItem(atPath: fileURL.path)
let createdAt = attributes?[.creationDate] as? Date ?? Date()
return Recording(url: fileURL, createdAt: createdAt)
}.sorted(by: { $0.createdAt > $1.createdAt })
} catch {
print("Error loading recordings: \(error)")
return []
}
}
func getEncryptionKey() -> SymmetricKey {
let keychainKey = "ziziapps.guardianangel.encryptionKey"
let keychainHelper = KeychainHelper()
if let keyData = keychainHelper.read(key: keychainKey) {
return SymmetricKey(data: keyData)
} else {
// Generate a new key if one doesn't exist, then store it
let newKey = SymmetricKey(size: .bits256)
let keyData = newKey.withUnsafeBytes { Data($0) }
keychainHelper.save(keyData, key: keychainKey)
return newKey
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79468531/voice-recording-watchos-application-gets-closed-after-several-hours[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия