I use AVSpeechSynthesizer to pronounce some text in German. Sometimes it works just fine and sometimes it doesn't for some unknown to me reason (there is no error, because the speak() method doesn't throw and the only thing I am able to observe is the following message logged in the console):
_BeginSpeaking: couldn't begin playback
I tried to find some API in the AVSpeechSynthesizerDelegate to register a callback when error occurs, but I have found none.
The closest match was this (but it appears to be only available for macOS, not iOS):
https://developer.apple.com/documentation/appkit/nsspeechsynthesizerdelegate/1448407-speechsynthesizer?changes=_10
Below you can find how I initialize and use the speech synthesizer in my app:
class Speaker: NSObject, AVSpeechSynthesizerDelegate {
class func sharedInstance() -> Speaker {
struct Singleton {
static var sharedInstance = Speaker()
}
return Singleton.sharedInstance
}
let audioSession = AVAudioSession.sharedInstance()
let synth = AVSpeechSynthesizer()
override init() {
super.init()
synth.delegate = self
}
func initializeAudioSession() {
do {
try audioSession.setCategory(.playback, mode: .spokenAudio, options: .duckOthers)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
}
}
func speak(text: String, language: String = "de-DE") {
guard !self.synth.isSpeaking else { return }
let utterance = AVSpeechUtterance(string: text)
let voice = AVSpeechSynthesisVoice.speechVoices().filter { $0.language == language }.first!
utterance.voice = voice
self.synth.speak(utterance)
}
}
The audio session initialization is ran during app started just once.
Afterwards, speech is synthesized by running the following code:
Speaker.sharedInstance.speak(text: "Lederhosen")
The problem is that I have no way of knowing if the speech synthesis succeeded—the UI is showing "speaking" state, but nothing is actually being spoken.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have been following these resources to set up auto-renewable subscriptions in my app written in SwiftUI:
What's new in StoreKit (WWDC17)
Advanced StoreKit (WWDC17)
https://blckbirds.com/post/how-to-use-in-app-purchases-in-swiftui-apps/
I basically have a class that implements SKProductsRequestDelegate instantiated in SubscribeView that processes the transactions. I was able to complete the entire flow in Sandbox (got the receipt and the server notification, created a corresponding subscription entry in my database).
The response coming from the verifyReceipt endpoint is quite complex and I am not sure if I understand it correctly. I am looking for an easy solution to get the latest subscription state. I don't want to focus on churn rate or anything else now.
Questions:
Does on-device receipt get automatically modified when the user cancels or modifies the subscriptions or when the trial period ends? If yes, can I rely on resubmitting the latest receipt from the device to my backend in order to keep track of the latest subscription state? I could resubmit the latest receipt on app startup, the server would verify and possibly update the subscription.
In the Advanced StoreKit (WWDC17) talk, it is mentioned to implement SKProductsRequestDelegate as soon as possible (e.g. in the AppDelegate). Do I even need that if I already have that delegate implemented in the SubscribeView? If I understood correctly, the purpose of that would be to be notified of the transactions done after some time (subscription change, cancellation, entering grace period, etc.). I'd prefer to ignore these for now and just rely on resubmitting the latest receipt to check the current subscription.
I store the information whether the user has premium subscription in the KeyChain.
I just have a global function called doesUserHavePremium that reads a value from the KeyChain.
It appears that sometimes that value is read from the KeyChain incorrectly—even though I am 100% sure it is set, it returns nil. This happens only when the app was launched, then left for some time (probably screen got locked), and then I reentered the app again without relaunching it from scratch.
I tried the following things:
loosening the KeyChain access the the least restrictive
the following piece of code to notify UI elements whenfalse/trueis read for that value after previously not being able to access it
let protectedDataAvailabilityNotificationName = UIApplication.protectedDataDidBecomeAvailableNotification
func observeProtectedDataAvailability() {
let selector = #selector(Self.protectedDataAvailableNotification)
switch UIApplication.shared.isProtectedDataAvailable {
case true: break
case false:
NotificationCenter.default.addObserver(self,
selector: selector,
name: protectedDataAvailabilityNotificationName,
object: nil)
}
}
@objc func protectedDataAvailableNotification(notification: NSNotification) {
NotificationCenter.default.removeObserver(self, name: protectedDataAvailabilityNotificationName, object: nil)
dataDidBecomeAvailable()
}
func dataDidBecomeAvailable() {
refreshSubscriptionStatusSubscribers()
}
But it doesn't seem to work. The problem is that I cannot debug it, because the app has to enter background in order for this problem to manifest itself.
I have read several threads related to this issue here and on GitHub and it seems like there isn't any great solution. I am looking for some workarounds. Any hints are welcome. I will try the following now:
Try to store that value in UserDefaults instead—it is not really a secret like a password/token, but I need to be sure it cannot be tampered with. Not sure if UserDefaults suffer from the same problem.
Try to refactor to code to wrap the doesUserHavePremium and cache its return value in a property. That seems promising, because it never happens during fresh start thus I could always set that property on the app startup.
Hi,
I have launched an app built with SwiftUI for iOS 14+.
It turned out that SwiftUI for iOS 15+ introduced some quite important changes for my app (most of all better support for NavigationLinks and managing keyboard with FocusState).
From now on, I'd like to only release updates for iOS 15+, but I don't want to lose any users and any ratings/reviews on the App Store.
Could someone please let me know what the exact outcomes of setting the deployment target to a newer iOS are?
Is it that the users with iOS older than iOS 15, will simply not see/receive updates? Will all the ratings and reviews be intact?
Thank you
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
App Store Connect
iOS
Xcode
My language learning app needs to support a lot of languages and text paragraphs containing 2 different languages are not uncommon. (e.g. German grammar explained in Arabic)
Now, I want to integrate a custom font to make the design unique and consistent across multiple platforms (iOS, Android, Web), but there is basically no single Font that supports all languages.
The question is:
What is the recommended way of implementing that on the code level in SwiftUI?
If I just hardcode:
.font(Font.custom("myFont", size: 16))
then I guess it is not gonna work if the text contains a language not supported by my custom font.
The Apple's default font seems to handle all languages perfectly, even if they are mixed together and I'd like to have something like that, but with a custom font.
Specifically, I'd like to integrate FF Din font:
https://www.myfonts.com/fonts/fontfont/ff-din/
with supported Languages: Western Europe, Vietnamese, Central/Eastern Europe, Baltic, Turkish, Romanian, Cyrillic, Greek
So I am wondering what I would do about Chinese, Arabic, etc.
Thanks
Hi,
I am receiving some bug reports from the users of my app and I would like to either thank you or ask for details via email.
The use the "hide my email" option, which makes it harder for me to just directly write them an email. I have configured SendGrid to support Apple Email Relay when sending emails programmatically, but I'd like to have a quick and easy way to just write a single email or two sometimes.
What would be the easiest way to be able to send an email from Gmail to someone using Apple Email Relay?
Thank you!
Hi,
I have a 12 months subscription which I generated some offer codes for. I generated 25000 of them manually in App Store Connect (One-Time Use Codes).
I want to send those codes to users by push notifications and I need to show the final price when the code will be applied. The problem is that I use the native sheet, which only shows the price after the user entered the code.
Is there an API that I can hook into to retrieve that price?
Otherwise, the best I could do would be to calculate ActualPrice * Discount (because I know the discount since I created the codes), but I am afraid it will not be accurate enough, because it is not possible to select price for offer codes with that precision.
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
Subscriptions
StoreKit
App Store Connect
In-App Purchase