Just ran into this. Thanks for the work-around.
Post
Replies
Boosts
Views
Activity
I know that this is an old thread and all, but I am wondering what is required to set in the plist to get a custom app extension icon? All my attempts have just resulted in the host icon being shown in an AUv3 host.
Brad
Unfortunately, my app is stuck in review limbo/hell because I mistakenly checked that box once and now Apple's site thinks it is still checked for some reason, even though it is not when I go to the "Age Rating" pages. Below is the first page - I cannot choose certain options because apparently "Made for Kids" is still set somewhere":
Here is screen 2 of 3, still with buttons disabled because of the phantom "Made for Kids":
Curiously, I can set that there is gambling, but when I do, I am unable to "Save" the changes.
Finally, page 3 of 3 that shows that indeed the "Made for Kids" setting is not set:
But submitting this will lead to a rejection because for whatever reason Apple's own system still thinks that this checkbox is set.
Here's some logging to show the sequence of events. The image below shows my constructor being called to create my custom AUAudioUnit. After construction, there is a solitary call to internalRenderBlock. The audio unit is part of a graph but the graph has not been started yet.
Here are the log lines after the graph starts and audio is flowing:
There is a second call to internalRenderBlock before my allocateRenderResources method is invoked. When rendering starts, my audio unit's own allocateRenderResources method is invoked, and when I call AUAudioUnit's allocateRenderResources, the internalRenderBlock is called a third time. After that, no more.
I noticed this as well. I think this is due to a circular reference between the audio unit and the AudioUnitBusArray instances which hold a reference to the audio unit. I changed my code to always return a new instance of AudioUnitBusArray:
override public var inputBusses: AUAudioUnitBusArray { .init(audioUnit: self, busType: .input, busses: [inputBus]) }
override public var outputtBusses: AUAudioUnitBusArray { .init(audioUnit: self, busType: .output, busses: [outputBus]) }
Also, make sure you use [weak self] for your parameter tree blocks, and any other similar blocks:
parameters.parameterTree.implementorValueProvider = { [weak self] param in
self?.kernel.get(param) ?? AUValue(0)
}
parameters.parameterTree.implementorValueObserver = { [weak self] param, value in
self?.kernel.set(param, value: value)
}
I have test cases that make sure I get an AUValue(0) from the parameter tree after nulling out a reference to my audio unit.
To answer your original question, you can only save certain elements in UserDefaults, and a PersistentIdentifier is not one of them. This type does implement the Codable protocol, so you can use something like JSON encoding/decoding to save to and restore from UserDefaults.
func saveValue(_ newValue: PersistentIdentifier, to store: UserDefaults, at key: String) {
let encoder = JSONEncoder()
store.setValue(try! encoder.encode(newValue), forKey: key)
}
func restoreValue(from store: UserDefaults, at key: String) -> PersistentIdentifier? {
guard let raw = store.data(forKey: key) else {
return nil
}
let decoder = JSONDecoder()
return try? decoder.decode(PersistentIdentifier.self, from: raw)
}