Post

Replies

Boosts

Views

Activity

16 Channel Compressed Audio Support?
We have an ambisonics renderer that requires 16 channel audio. Everything works fine using AVAudioFile to read a wav file with AVAudioChannelLayout.init(layoutTag: kAudioChannelLayoutTag_HOA_ACN_SN3D | 16) into AVAudioPCMBuffer but the raw wav files are huge. I can't find any compressed formats (lossy or lossless) that iOS is able to read at 16 channels. Whilst it seems possible to create an aac file with up-to 48 channels iOS doesn't seem able to decode anything with more than 8 channels (7.1) as far as I can tell? I considered using 2x8 channel aac files, reading them into 2 buffers and then joining them but have been unable to figure out how to merge them back to 16 channels with the correct layout. I'm currently experimenting with trying to use Ogg/Opus for the compression as an alternative but my experiments here have also been unsuccessful so far. Any help anyone can give on how I could go about getting 16 channels of compressed audio out of a file (or files) and into an AVAudioPCMBuffer with kAudioChannelLayoutTag_HOA_ACN_SN3D | 16 layout would be very amazing.
0
0
1.1k
Jun ’21
Is it possible to share an app group between Catalyst and AppKit Apps?
I have 2 Apps. A sandboxed native Mac App written in AppKit/SwiftUI. A Catalyst App. I would like them to be able to communicate with each other. I assumed I would be able to do this using a shared App Group but I can't get it to work and I think this is because the App Group naming conventions appear to be different. As far as I can make out: A Mac App uses App groups prefixed with the team ID A Catalyst App uses the iOS App groups which are prefixed with group. I have tried multiple combinations of different prefixes to try and make this work but without success. I have been "testing" this by using UserDefaults(suiteName: appGroup) and then attempting to read write values between the 2 Apps but without success so far. My questions are: Is sharing an App Group between Catalyst and native technically possible? If it is possible what is the magic combo of App Group prefixes that makes it work? If it is not possible then do I have any other options for communicating between a sandboxed Mac App and a Catalyst App?
2
0
1.3k
Jun ’22
Transaction.updates stream closes immediately for some customers
We have code similar to the following in our App. Task.detached(priority: .background) { logger.log("starting listening for transaction updates") defer { logger.warning("stopped listening for transaction updates") } for await verificationResult in Transaction.updates { logger.log("processing transaction update") ... } } } This code gets run on App launch. From looking at logs for some customers in production, on macOS 13.4.1, it seems as though "stopped listening for transaction updates" gets logged almost immediately after "starting listening for transaction updates" and before any "processing transaction update" messages. My original guess was that maybe this was caused by the user being logged out of the AppStore but this doesn't seem to be the case and I have been totally unable to reproduce it. A customer suggested that it happens every time they received an App update from from the App Store but the may be correlation rather than causation. I can see from looking at the customers logs that they also don't appear to have an AppTransaction available when this situation happens. My question is, under what conditions can the Transaction.updates stream get closed early like this? What action should we take in this scenario? Would restarting the stream again lead to an infinite start/stop loop?
1
0
716
Jul ’23
Expired intermediate certificates in StoreKit 2 JWS
We send StoreKit 2 signed transactions to our server for validation and processing. As part of this process, as recommended by Apple, we validate the certificate chain against the "Apple Root CA - G3 Root" certificate found here: https://www.apple.com/certificateauthority/ As of 24th September we started noticing this validation erroring because of expired certificates in the JWT. On further investigation we see the first cert in the chain, with the common name "Prod ECC Mac App Store and iTunes Store Receipt Signing", appears to have expired at "Sep 24 02:50:33 2023 GMT" I checked and calling the App Store API at "inApps/v1/subscriptions/" with the same transaction id also returns the subscription with the same expired certificate in the chain so I am confident that this is a genuine transaction issued by Apple. For now we have been forced to disable validating the expiry date of intermediate certificates to work around this. I'm however really surprised I haven't found anyone else discussing this or any documentation around how to handle this situation. Is it expected that the App Store JWS would contain an expired certificate and what is the guidance on how to proceed in this situation?
2
0
834
Sep ’23
Cannot sign in to TestFlight App on macOS
Since updating to 14.2 beta 2 I see the following error when trying to sign in to the TestFlight App on macOS. "Password reuse not available for account" It seems like it possibly affecting the AppStore too, from the device logs I see: Error Domain=AMSErrorDomain Code=2 \"Password reuse not available for account\" UserInfo={NSLocalizedDescription=Password reuse not available for account, NSLocalizedFailureReason=The account state does not support password reuse.}" I've tried signing out of the App Store to fix it but now I can't sign into either the store of TestFlight. I've also tried, multiple restarts and safe mode. Things seem fine on other platforms. Is this a known issue? Are others seeing it? Any ideas for how to reset things or what the error might be referring to?
4
1
1.6k
Nov ’23
AVAudioPlayerNode scheduleBuffer & Swift 6 Concurrency
We do custom audio buffering in our app. A very minimal version of the relevant code would look something like: import AVFoundation class LoopingBuffer { private var playerNode: AVAudioPlayerNode private var audioFile: AVAudioFile init(playerNode: AVAudioPlayerNode, audioFile: AVAudioFile) { self.playerNode = playerNode self.audioFile = audioFile } func scheduleBuffer(_ frames: AVAudioFrameCount) async { let audioBuffer = AVAudioPCMBuffer( pcmFormat: audioFile.processingFormat, frameCapacity: frames )! try! audioFile.read(into: audioBuffer, frameCount: frames) await playerNode.scheduleBuffer(audioBuffer, completionCallbackType: .dataConsumed) } } We are in the migration process to swift 6 concurrency and have moved a lot of our audio code into a global actor. So now we have something along the lines of import AVFoundation @globalActor public actor AudioActor: GlobalActor { public static let shared = AudioActor() } @AudioActor class LoopingBuffer { private var playerNode: AVAudioPlayerNode private var audioFile: AVAudioFile init(playerNode: AVAudioPlayerNode, audioFile: AVAudioFile) { self.playerNode = playerNode self.audioFile = audioFile } func scheduleBuffer(_ frames: AVAudioFrameCount) async { let audioBuffer = AVAudioPCMBuffer( pcmFormat: audioFile.processingFormat, frameCapacity: frames )! try! audioFile.read(into: audioBuffer, frameCount: frames) await playerNode.scheduleBuffer(audioBuffer, completionCallbackType: .dataConsumed) } } Unfortunately this now causes an error: error: sending 'audioBuffer' risks causing data races | `- note: sending global actor 'AudioActor'-isolated 'audioBuffer' to nonisolated instance method 'scheduleBuffer(_:completionCallbackType:)' risks causing data races between nonisolated and global actor 'AudioActor'-isolated uses I understand the error, what I don't understand is how I can safely use this API? AVAudioPlayerNode is not marked as @MainActor so it seems like it should be safe to schedule a buffer from a custom actor as long as we don't send it anywhere else. Is that right? AVAudioPCMBuffer is not Sendable so I don't think it's possible to make this callsite ever work from an isolated context. Even forgetting about the custom actor, if you instead annotate the class with @MainActor the same error is still present. I think the AVAudioPlayerNode.scheduleBuffer() function should have a sending annotation to make clear that the buffer can't be used after it's sent. I think that would make the compiler happy but I'm not certain. Am I overlooking something, holding it wrong, or is this API just pretty much unusable in Swift 6? My current workaround is just to import AVFoundation with @preconcurrency but it feels dirty and I am worried there may be a real issue here that I am missing in doing so.
3
0
496
Aug ’24
macOS App Group Entitlements
We have a cross platform App available on Mac, iOS & soon tvOS. We are adding a new App Group to be used by this app. We also have a as yet unpublished future Mac Catalyst app that will need access to the App Group. The Apple docs suggest prefixing app groups on Mac with the team ID but not on other platforms. We would like to avoid prefixing with the team ID because: my understanding is that Mac Catalyst apps don't use the team ID and we would like to support that use case to communicate between our current cross platform app and the future catalyst app. Having a single code base but different group container IDs per platform means a bunch of extra conditional logic in the project we would rather avoid. So with that context our aim is to have an app group that is named consistently across platforms and meets sandboxing requirements for App Store distribution. However when developing using the non-team prefixed app group name on macOS Sequioa I see the following alert every time I launch the app. I have the App Group listed correctly in the entitlements file and if I change the app group name on macOS from group.com.example to (TEAMID).com.example then it works as expected so I think the rest of the setup is correct. Looking at the Sequoia Beta release notes it states: Specifically, the app must use FileManager to get the app group container path and meet one of the following requirements: the app is deployed through Mac App Store; the app group identifier is prefixed with the app’s Team ID; or the app group identifier is authorised by a provisioning profile embedded within the app. I am using Xcode managed signing and looking at the provisioning profiles I can see that the iOS one includes the app group but the macOS one does not. I assume that if I could somehow get the app group correctly add to the macOS provisioning profile then all would be good. But I am now stuck on how to get the app group added to the macOS provisioning profile. It seems whatever I try Xcode does not want to add it. Presumably this is because it expects you to instead use a team ID prefixed app group which would not need to be added. Is there any magic I can do to make this work with automatic signing? If not then how would I go about setting it up manually and is that the best solution?
1
1
549
Aug ’24
Symbol missing when building in Xcode cloud with Xcode 16 beta and running on macOS 14.6
We have a cross platform app that we build with Xcode Cloud and distribute via TestFlight. We want to test builds with the Xcode Beta. So we have the following build environment: Xcode version: Xcode 16 beta 6 (16A5230g) macOS Version: macOS Sonoma 14.5 (23F79) Everything builds and submits to TestFlight fine. The App runs fine on iOS 18 beta and macOS 15 beta. But when attempting to install via TestFlight and launch the App on macOS 14..6.1 it crashes immediately with what appears to be a missing Foundation symbol. Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: Namespace DYLD, Code 4 Symbol missing Symbol not found: _$s10Foundation14NSDecimalRoundyySpySo0B0aG_SPyADGSiSo14NSRoundingModeVtF Referenced from: <CBEBC813-C7B6-3D8E-BE62-16F2EFFEB1FE> /Applications/MyApp.app/Contents/MacOS/MyApp Expected in: <2F87A303-430F-3EA5-9492-3033F4FEE64B> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (terminated at launch; ignore backtrace) Thread 0 Crashed: 0 dyld 0x7ff8139f687a __abort_with_payload + 10 1 dyld 0x7ff813a0f7f7 abort_with_payload_wrapper_internal + 82 2 dyld 0x7ff813a0f829 abort_with_payload + 9 3 dyld 0x7ff81399c2b5 dyld4::halt(char const*, dyld4::StructuredError const*) + 335 4 dyld 0x7ff8139994bd dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 4099 5 dyld 0x7ff8139982e4 start + 1812 Is it expected that this should work? Is this a known issue? Is there any workaround for it? Should I file feedback or a DTS?
11
4
1.6k
Aug ’24
URLRepresentableEntity with custom properties
I am trying to implement URLRepresentableEntity on my AppEntity I am following along with the WWDC video here All compiles fine when I use the ID as in the video: extension SceneEntity: URLRepresentableEntity { static var urlRepresentation: URLRepresentation { "https://example.com/scene/\(.id)" } } but my URLs need to use a different property on the Entity. The WWDC video clearly states: "Notice that I'm using the entity’s identifier as an interpolated value. You can use an entity’s ID or any of its properties with the @Property attribute as interpolations in the URL string." So I annotated my entity with the @Property attribute and expected that to work but it doesn't compile. struct SceneEntity: AppEntity { let id: UUID @Property(title: "Slug") var slug: String } extension SceneEntity: URLRepresentableEntity { static var urlRepresentation: URLRepresentation { "https://example.com/scene/\(.slug)" } } Type 'EntityURLRepresentation.StringInterpolation.Token' has no member 'slug' How can I use this API with a property that is not the ID?
0
0
332
Sep ’24