Hello,
Recently I've been hitting on a problem when using WKExtendedRuntimeSession with SwiftUI
I have created a ObservedObject like this:
@ObservedObject var store = TimerStore()
when the view appears I call upon
store.startTimer()
the timer store object looks like this:
class TimerStore : NSObject, ObservableObject, WKExtendedRuntimeSessionDelegate {
@Published var secondsPassed : Int {
didSet { didChange.send() }
}
var timer : Timer!
var extSession: WKExtendedRuntimeSession!
init(seconds: Int = 0) {
self.secondsPassed = seconds
}
var didChange = PassthroughSubject<Void, Never>()
func startTimer() {
timer = Timer.scheduledTimer(
timeInterval: 1,
target: self,
selector: (#selector(self.updateSeconds)),
userInfo: nil,
repeats: true
)
startSession()
}
@objc func updateSeconds() {
self.secondsPassed += 1
}
func startSession() {
extSession = WKExtendedRuntimeSession()
extSession.delegate = self
extSession.start()
}
func stopSession() {
extSession.invalidate()
timer.invalidate()
}
func extendedRuntimeSession(_ extendedRuntimeSession: WKExtendedRuntimeSession, didInvalidateWith reason: WKExtendedRuntimeSessionInvalidationReason, error: Error?) {
print("Session stopped: \(Date())")
}
func extendedRuntimeSessionDidStart(_ extendedRuntimeSession: WKExtendedRuntimeSession) {
print("Session started: \(Date())")
}
func extendedRuntimeSessionWillExpire(_ extendedRuntimeSession: WKExtendedRuntimeSession) {
print("Session expired: \(Date())")
}
}
When I debug it with my phone attached it offers no problems and it clearly prints out the start and end of the session, even after waiting for 10min (when the session would be expired), however when I keep using the app after debugging the extended runtime session doesn't work anymore on the device.
I've tried a lot but it's blowing my mind. When talking with a Apple developer via Labs last week he said it could be because views in SwiftUI are not permanent .
I do get it to work when I use a storyboard + WatchKit
Does anyone has any idea how I can potentially fix this?
Post
Replies
Boosts
Views
Activity
Hello,
I'm looking for a way I can achieve multiple pages on watchOS in the new SwiftUI App Structure.
In Storyboard you can set a relationship segue "next page". But does anyone know how to achieve this in SwiftUI without using storyboards.
I expected to find something for this in WindowGroup but without success.
Or do I need to change my design to have one screen instead.
Hey all,
I've been using StoreKit 2 lately and I'm so deeply impressed with how much easier it has become.
For a better user experience regarding transaction history, I've built a view that would show every transaction made in the past with the option to request a refund natively.
The only problem I'm facing at the moment is that I can't seem to get a list with all transactions, my app has Non-consumable, Consumable and Subscription IAP and I only get the Non-consumable + Subscriptions when I use the Transaction.all
Does anyone have any idea how I can get the Consumable transactions as well?
Current code
@MainActor
func getPurchasedProducts() async {
//Iterate through all of the user's purchased products.
for await result in StoreKit.Transaction.all {
if case .verified(let transaction) = result {
if !self.transactions.contains(transaction) {
self.transactions.append(transaction)
self.transactions = sortByDate(self.transactions)
}
}
}
}
For my app that heavily uses both ShazamKit and MusicKit, I need to be able to check if the matched song is in the user's library or not.
I couldn't find an easy way to do this with MusicKit so I first then turned to the Apple Music API as they introduced the new parameter
?relate=library during this year's WWDC.
When I first tried it, it worked as expected, and was very happy to have gotten it to work. However, it stopped working lately and now I turned to use MPMediaLibrary as that still works but is a lot slower in performance.
Anyone has any idea why the ?relate=library stopped working for me or know a better way to check if the Song exists in the user's library?
func checkInLibrary(from appleMusicID: String) async {
do {
let countryCode = try await MusicDataRequest.currentCountryCode
let libURL = URL(string: "https://api.music.apple.com/v1/catalog/\(countryCode)/songs/\(appleMusicID)?relate=library")!
let request = MusicDataRequest(urlRequest: URLRequest(url: libURL))
let dataResponse = try await request.response()
print(dataResponse.debugDescription)
}
catch { // I'm handling errors here }}
I recently released my first ShazamKit app, but there is one thing that still bothers me.
When I started I followed the steps as documented by Apple right here : https://developer.apple.com/documentation/shazamkit/shsession/matching_audio_using_the_built-in_microphone
however when I was running this on iPad I receive a lot of high pitched feedback noise when I ran my app with this configuration. I got it to work by commenting out the output node and format and only use the input.
But now I want to be able to recognise the song that’s playing from the device that has my app open and was wondering if I need the output nodes for that or if I can do something else to prevent the Mic. Feedback from happening.
In short:
What can I do to prevent feedback from happening
Can I use the output of a device to recognise songs or do I just need to make sure that the microphone can run at the same time as playing music?
Other than that I really love the ShazamKit API and can highly recommend to have a go with it!
This is the code as documented in the above link (I just added the comments of what broke it for me)
func configureAudioEngine() {
// Get the native audio format of the engine's input bus.
let inputFormat = audioEngine.inputNode.inputFormat(forBus: 0)
// THIS CREATES FEEDBACK ON IPAD PRO
let outputFormat = AVAudioFormat(standardFormatWithSampleRate: 48000, channels: 1)
// Create a mixer node to convert the input.
audioEngine.attach(mixerNode)
// Attach the mixer to the microphone input and the output of the audio engine.
audioEngine.connect(audioEngine.inputNode, to: mixerNode, format: inputFormat)
// THIS CREATES FEEDBACK ON IPAD PRO
audioEngine.connect(mixerNode, to: audioEngine.outputNode, format: outputFormat)
// Install a tap on the mixer node to capture the microphone audio.
mixerNode.installTap(onBus: 0,
bufferSize: 8192,
format: outputFormat) { buffer, audioTime in
// Add captured audio to the buffer used for making a match.
self.addAudio(buffer: buffer, audioTime: audioTime)
}
}
Hey All,
Loving the MusicKit API but have one question regarding the .musicSubscriptionOffer(isPresented:options:onLoadCompletion:). When Apple Music is not installed on the device it can't be presented, is there any way to still present the musicSubscriptionOffer or do I have to prompt the user to install Apple Music first?
and if so, what's the best way to check if Apple Music is installed?
Hi There,
In the documentation of MusicKit's Song object I can find the hasLyrics property, with the following description:
A Boolean value that indicates whether the song has lyrics available in the catalog. If true, the song has lyrics available; otherwise, it doesn’t.
My only question now is, where can I find the lyrics if this returns true? What is "the catalog" in this case.
I hope the lyrics are available in MusicKit or the Apple Music API as this would save me a lot of headache connecting more API's (lyrics is one of my most requested feature)
I'm switching my business model to freemium and now I need a clean way to keep giving access to all features for my existing userbase.
I know I probably should do something with receipt validation but which receipt do I check and is there a very clean and straightforward way of doing this with StoreKit 2 maybe?
I would have loved to see something like:
AppStore.originalPurchaseDate property in StoreKit 2 but would love to hear some thoughts and input!
Hi There,
I've created a little tool for myself to quickly find the MusicItemID of a song which I then use in one of my own APIs to match the content.
In this tool, I'm using the MusicCatalogSearchRequest but I was just wondering if anyone knows if those IDs I get back from this request are unique to the locale? and if so, is there a way to get all the IDs of a song to write down?
I don't want to match on a name as that's more error prone.
e.g. my API would look something like this:
{
"id": ["1259176472","510004981","1302212469"],
"text": "Cool content.",
}
Hi There,
Whenever I want to use the microphone for my ShazamKit app while connected to AirPods my app crashes with a "Invalid input sample rate." message.
I've tried multiple formats but keep getting this crash. Any pointers would be really helpful.
func configureAudioEngine() {
do {
try audioSession.setCategory(.playAndRecord, options: [.mixWithOthers, .defaultToSpeaker, .allowAirPlay, .allowBluetoothA2DP ,.allowBluetooth])
try audioSession.setActive(false, options: .notifyOthersOnDeactivation)
} catch {
print(error.localizedDescription)
}
guard let engine = audioEngine else { return }
let inputNode = engine.inputNode
let inputNodeFormat = inputNode.inputFormat(forBus: 0)
let audioFormat = AVAudioFormat(
standardFormatWithSampleRate: inputNodeFormat.sampleRate,
channels: 1
)
// Install a "tap" in the audio engine's input so that we can send buffers from the microphone to the signature generator.
engine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: audioFormat) { buffer, audioTime in
self.addAudio(buffer: buffer, audioTime: audioTime)
}
}
```
Hi All,
I recently decided to remove my localizations for now because I'm requesting content from a lot of different sources (many of which only provides English text.
But with MusicKit I still receive the locale content. So basically I'm wondering if it's possible to set a locale for a MusicCatalogResourceRequest?
Hey there,
I was wondering if it's possible to check how "certain" ShazamKit is with the match.
For example; I'd only change the result when the SHMatch has an accuracy/certainty of at least 80%
I know there's a frequencySkew on the SHMatchedMediaItem but I'm not sure if that could be helpful
The new MusicLibraryRequest<Playlist>() is great to get all the user's playlists but I have not found a way to exclude a specific type of playlist. For example; I wish to only get playlists that the user owns and can add content to (so this would exclude Smart and Curated playlists)
I did find the Playlist.Kind enum, but I can't seem to apply this to the request, and it doesn't seem to have an option for smart playlists.
So in short:
Is there any way I can exclude Smart- and Curated Playlists from a MusicLibraryRequest
Hey All,
I'm currently implementing the new NavigationSplitView to improve my app's iPad experience, but I noticed that I couldn't seem to be able to tint the icons provided to toggle the Sidebar and the overflow menu.
If I can't change the tint of these icons, I'm afraid I have to fall back the old implementation.
The same counts for the Customize toolbar view. (I would also love to be able to change that background for legibility)
Hey All
I've been looking at adding a visual representation of the song's first genre in my app and therefor was wondering if there's a list available somewhere of all the Genre's available in MusicKit and their IDs
e.g. Genre(id: "21", name: "Rock", parent: Genre(id: "34", name: "Music"))
So my questions:
Is there a list of all IDs?
Are these IDs the same in every country?
The reason why I would want this is to have my visuals be safe for localization. For example: If I'd call my asset icon-electronic and then localize my app in dutch it would ask for icon-electronisch. I hope this makes sense and I hope I don't have to browse and save a list of all Genre's by hand haha