Audiokit 4.9.5 вылетает в xcode 11.4 + swift 5.2, полезного сообщения об ошибке нет - PullRequest
1 голос
/ 25 апреля 2020

При импорте AudioKit и попытке запустить небольшой пример я получаю:

Error Domain=com.apple.dt.ultraviolet.service Code=12 "Rendering service was interrupted" UserInfo={NSLocalizedDescription=Rendering service was interrupted}

После тестирования много раз я заметил, что он падает только в режиме «Предварительный просмотр (правая боковая панель)» , так как он «строит» и работает в «симуляторе». Это ограничение функции preview в Xcode? Я не знаю, но сообщил команде AudioKit (https://github.com/AudioKit/AudioKit/issues/2034)

Учитывая hello world, опубликованный в (https://audiokit.io/examples/HelloWorld/), я -писал немного по-другому, чтобы соответствовать последним (учитывая время написания) Xcode 11.4 и Swift 5.2:

import SwiftUI
import AudioKit

struct ContentView: View {
    var oscillator = AKOscillator()
    var body: some View {
        VStack {
            Button("Play") {
                self.playSound()
            }
        }.onAppear {
            do {
                AudioKit.output = self.oscillator
                try AudioKit.start()
            } catch {
                print("audiokit init error")
            }
        }
    }

    private func playSound(){
        self.oscillator.amplitude = 1
        self.oscillator.frequency = 440
        self.oscillator.start()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Подфайл:

platform :ios, '11.0'

target 'AKHello' do
  use_frameworks!

  # Pods for AKHello
  pod 'AudioKit', '~> 4.9.5'

end

Есть ли какой-то синтаксис ошибка в исходном коде или способ получить более значимую или полезную ошибку, чтобы это вообще исправить? AudioKit кажется совместимым с последней версией Xcode 11.4, учитывая примечания к выпуску на странице github (https://github.com/AudioKit/AudioKit/releases, где вы можете прочитать: «Этот выпуск в основном содержит новые двоичные файлы, совместимые с последней версией Xcode через CocoaPods»)

Поскольку инициализация AudioKit в View, вероятно, не очень хорошая практика (и хотя цель состоит в том, чтобы просто запустить простой мир Hello, просто чтобы убедиться, что я переместил эту часть в struct, но возникает та же проблема)

// AudioPlayer.swift

import AudioKit

struct AudioPlayer {
    var oscillator = AKOscillator()
    init() {
        do {
            AudioKit.output = self.oscillator
            try AudioKit.start()
        } catch {
            print("audiokit init error")
        }
    }

    func playSound(){
        self.oscillator.amplitude = 1
        self.oscillator.frequency = 440
        self.oscillator.start()
    }
}

// ContentView.swift


import SwiftUI

struct ContentView: View {
    var audioPlayer: AudioPlayer = AudioPlayer()
    var body: some View {
        VStack {
            Button("Play") {
                self.audioPlayer.playSound()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Также пробуется как наблюдаемая, с соответствующими изменениями в представлении содержимого и делегате сцены, где я передаю новый класс для аудиоплеера:

// ContentView.swift

import SwiftUI

struct ContentView: View {
    @ObservedObject var audioPlayer: AudioPlayer

    var body: some View {
        VStack {
            Button("Play") {
                self.audioPlayer.playSound()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(audioPlayer: AudioPlayer())
    }
}

// AudioPlayer.swift

import AudioKit
import Combine

class AudioPlayer: ObservableObject {
    let objectWillChange = PassthroughSubject<AudioPlayer, Never>()
    var isPlaying = false {
        didSet {
            objectWillChange.send(self)
        }
    }
    var oscillator = AKOscillator()

    init() {
        do {
            AudioKit.output = self.oscillator
            try AudioKit.start()
            isPlaying = true
        } catch {
            print("audiokit init error")
        }
    }

    func playSound(){
        self.oscillator.amplitude = 1
        self.oscillator.frequency = 440
        self.oscillator.start()
    }
}

// SceneDelegate.swift

import UIKit
import SwiftUI

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?


    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        let contentView = ContentView(audioPlayer: AudioPlayer())

        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}

1 Ответ

1 голос
/ 26 апреля 2020

Я не уверен, что это вся ваша проблема, но не ожидайте, что AudioKit будет работать в режиме предварительного просмотра. Насколько я знаю, это должен быть только визуальный материал типа SwiftUI. Ваш первый подход, когда жизненный цикл AudioKit был связан с SwiftUI, был довольно опасным. Помните, что SwiftUI будет делать все, что нужно, и вам не следует доверять аудиосистеме, чтобы она работала внутри нее. Затем вы переместили аудиоплеер в его собственный класс, но я все еще беспокоюсь, что вы слишком тесно связываете жизненный цикл со структурами SwiftUI. Мой подход состоял бы в том, чтобы переместить аудио движок в его собственный класс, созданный в SceneDelegate и затем запущенный в onAppear для основного представления контента. Посмотрите папку примеров AudioKit для iOS + Catalyst / Drums / для примера того, как вы должны настроить это.

...