We currently have an odd issue with VoiceOver spelling a word letter by letter while the same word is spoken as a whole for other items.
The app is in German.
I have a View in SwiftUI whose button traits are removed, then a label "Start Tab 1 von 5" is added. "Tab is spoken as a whole word here, all fine.
If I change the label to "Tab-Schaltfläche" or for example "SimplyGo Tab 3 von 5", then "Tab" is spoken as "T A B", letter by letter. is there a way to force VoiceOver to speak it as a whole?
Post
Replies
Boosts
Views
Activity
Hey!
I noticed a difference between Xcode 15.2 and 15.3 which causes our production build to fail verification with Apple. This happens with one Swift Package which has xcframeworks as binary targets. There is no issue when exporting the app using Xcode 15.2, as the frameworks are not exported into the Frameworks folder within the app package when inspecting the exported archive. With Xcode 15.3 it is exported which then causes the following error:
2024-03-11 13:53:03.520 *** Error: ERROR: [ContentDelivery.Uploader] Asset validation failed (90208) Invalid Bundle. The bundle App.app/Frameworks/AppCenter.framework does not support the minimum OS Version specified in the Info.plist. (ID: 9e47cf5c-dc23-4cdf-8490-f9befc9e2aa1)
2024-03-11 13:53:03.521 *** Error: ERROR: [ContentDelivery.Uploader] Asset validation failed (90208) Invalid Bundle. The bundle App.app/Frameworks/AppCenterAnalytics.framework does not support the minimum OS Version specified in the Info.plist. (ID: 619289b3-c102-4161-8b63-73d42292a3cf)
2024-03-11 13:53:03.522 *** Error: ERROR: [ContentDelivery.Uploader] Asset validation failed (90208) Invalid Bundle. The bundle App.app/Frameworks/AppCenterCrashes.framework does not support the minimum OS Version specified in the Info.plist. (ID: ac590192-a99b-4aec-ad08-b21afadd10d0)
2024-03-11 13:53:03.522 *** Error: ERROR: [ContentDelivery.Uploader] Asset validation failed (90208) Invalid Bundle. The bundle App.app/Frameworks/AppCenterDistribute.framework does not support the minimum OS Version specified in the Info.plist. (ID: 69e0e8a6-11a7-46e5-9e5a-cf85c8fc15be)
2024-03-11 13:53:21.546 INFO: [ContentDelivery.Uploader]
=============
VERIFY FAILED with 4 errors.
=============
2024-03-11 13:53:21.548 *** Error: Validation failed for 'OEBB.ipa'.
2024-03-11 13:53:21.548 *** Error: Asset validation failed Invalid Bundle. The bundle App.app/Frameworks/AppCenter.framework does not support the minimum OS Version specified in the Info.plist. (ID: 9e47cf5c-dc23-4cdf-8490-f9befc9e2aa1) (90208)
{
NSLocalizedDescription = "Asset validation failed";
NSLocalizedFailureReason = "Invalid Bundle. The bundle App.app/Frameworks/AppCenter.framework does not support the minimum OS Version specified in the Info.plist. (ID: 9e47cf5c-dc23-4cdf-8490-f9befc9e2aa1)";
NSUnderlyingError = "Error Domain=IrisAPI Code=-19241 \"Asset validation failed\" UserInfo={status=409, detail=Invalid Bundle. The bundle App.app/Frameworks/AppCenter.framework does not support the minimum OS Version specified in the Info.plist., id=9e47cf5c-dc23-4cdf-8490-f9befc9e2aa1, code=STATE_ERROR.VALIDATION_ERROR.90208, title=Asset validation failed, NSLocalizedFailureReason=Invalid Bundle. The bundle App.app/Frameworks/AppCenter.framework does not support the minimum OS Version specified in the Info.plist., NSLocalizedDescription=Asset validation failed}";
"iris-code" = "STATE_ERROR.VALIDATION_ERROR.90208";
}
2024-03-11 13:53:21.548 *** Error: Asset validation failed Invalid Bundle. The bundle App.app/Frameworks/AppCenterAnalytics.framework does not support the minimum OS Version specified in the Info.plist. (ID: 619289b3-c102-4161-8b63-73d42292a3cf) (90208)
{
NSLocalizedDescription = "Asset validation failed";
NSLocalizedFailureReason = "Invalid Bundle. The bundle App.app/Frameworks/AppCenterAnalytics.framework does not support the minimum OS Version specified in the Info.plist. (ID: 619289b3-c102-4161-8b63-73d42292a3cf)";
NSUnderlyingError = "Error Domain=IrisAPI Code=-19241 \"Asset validation failed\" UserInfo={status=409, detail=Invalid Bundle. The bundle App.app/Frameworks/AppCenterAnalytics.framework does not support the minimum OS Version specified in the Info.plist., id=619289b3-c102-4161-8b63-73d42292a3cf, code=STATE_ERROR.VALIDATION_ERROR.90208, title=Asset validation failed, NSLocalizedFailureReason=Invalid Bundle. The bundle App.app/Frameworks/AppCenterAnalytics.framework does not support the minimum OS Version specified in the Info.plist., NSLocalizedDescription=Asset validation failed}";
"iris-code" = "STATE_ERROR.VALIDATION_ERROR.90208";
}
2024-03-11 13:53:21.548 *** Error: Asset validation failed Invalid Bundle. The bundle App.app/Frameworks/AppCenterCrashes.framework does not support the minimum OS Version specified in the Info.plist. (ID: ac590192-a99b-4aec-ad08-b21afadd10d0) (90208)
{
NSLocalizedDescription = "Asset validation failed";
NSLocalizedFailureReason = "Invalid Bundle. The bundle App.app/Frameworks/AppCenterCrashes.framework does not support the minimum OS Version specified in the Info.plist. (ID: ac590192-a99b-4aec-ad08-b21afadd10d0)";
NSUnderlyingError = "Error Domain=IrisAPI Code=-19241 \"Asset validation failed\" UserInfo={status=409, detail=Invalid Bundle. The bundle App.app/Frameworks/AppCenterCrashes.framework does not support the minimum OS Version specified in the Info.plist., id=ac590192-a99b-4aec-ad08-b21afadd10d0, code=STATE_ERROR.VALIDATION_ERROR.90208, title=Asset validation failed, NSLocalizedFailureReason=Invalid Bundle. The bundle App.app/Frameworks/AppCenterCrashes.framework does not support the minimum OS Version specified in the Info.plist., NSLocalizedDescription=Asset validation failed}";
"iris-code" = "STATE_ERROR.VALIDATION_ERROR.90208";
}
2024-03-11 13:53:21.548 *** Error: Asset validation failed Invalid Bundle. The bundle App.app/Frameworks/AppCenterDistribute.framework does not support the minimum OS Version specified in the Info.plist. (ID: 69e0e8a6-11a7-46e5-9e5a-cf85c8fc15be) (90208)
{
NSLocalizedDescription = "Asset validation failed";
NSLocalizedFailureReason = "Invalid Bundle. The bundle App.app/Frameworks/AppCenterDistribute.framework does not support the minimum OS Version specified in the Info.plist. (ID: 69e0e8a6-11a7-46e5-9e5a-cf85c8fc15be)";
NSUnderlyingError = "Error Domain=IrisAPI Code=-19241 \"Asset validation failed\" UserInfo={status=409, detail=Invalid Bundle. The bundle App.app/Frameworks/AppCenterDistribute.framework does not support the minimum OS Version specified in the Info.plist., id=69e0e8a6-11a7-46e5-9e5a-cf85c8fc15be, code=STATE_ERROR.VALIDATION_ERROR.90208, title=Asset validation failed, NSLocalizedFailureReason=Invalid Bundle. The bundle App.app/Frameworks/AppCenterDistribute.framework does not support the minimum OS Version specified in the Info.plist., NSLocalizedDescription=Asset validation failed}";
"iris-code" = "STATE_ERROR.VALIDATION_ERROR.90208";
}
The package used is the following: https://github.com/ilendemli/appcenter-sdk-apple-spm (package by me, using binary packages to avoid building AppCenter every time)
Comparison image: Left exported using Xcode 15.2 (works), right exported using 15.3 (fails)
Hi!
Currently I am facing an issue I don't fully understand.
I have to get the steps and distanceWalkingAndRunning and sync it to the backend periodically for which I have registered a BGTaskScheduler and created a request to trigger it every 15 minutes.
I understand that it's just a request to trigger it every 15 minutes, in reality the OS decides when to run it, no earlier than the set time.
For debugging purposes, one can trigger the task manually which I tried and succeeded. Works as expected.
App is running, the task gets registered and scheduled, I pause the app and send the command to trigger the task.
Upon resuming the app, my task gets executed, the HealthKit query goes through and submits the correct values to the backend.
Now to the issue. If I run the app normally, and wait for the task to get executed, for some reason the HealthKit query always returns 0, ergo syncing wrong values to the backend.
It's hard to debug this case, I have all the permission I need to read the data and works properly when run manually.
Either i need a special entitlement or this is a bug or I am missing something (most likely?). I hope to get some help here.
I have a class where I want to handle the Sign in with Apple logic. I have created an ASAuthorizationController, set the presentationContextProvider to be my view controller and set the delegate to the class itself. When I perform the requests, the system dialog shows up. But upon canceling, my delegate method does not get called.
Here is my class:
final class AppleSignInProvider: NSObject {
typealias CompletionHandler = (Result<AuthCredential, Error>) -> Void
enum AuthError: LocalizedError {
case credential
case nonce
case identityToken
case identityTokenString
}
private let completion: CompletionHandler
private var authorizationController: ASAuthorizationController?
init(completion: @escaping CompletionHandler) {
self.completion = completion
}
private var currentNonce: String?
private func sha256(nonce: String) -> String {
let inputData = Data(nonce.utf8)
let hashedData = SHA256.hash(data: inputData)
let hashString = hashedData.compactMap {
return String(format: "%02x", $0)
}.joined()
return hashString
}
func signIn(viewController: UIViewController) {
let nonce = randomNonceString()
currentNonce = nonce
let request = ASAuthorizationAppleIDProvider().createRequest()
request.requestedScopes = [
.fullName, .email
]
request.nonce = sha256(nonce: nonce)
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.presentationContextProvider = viewController.view.window
authorizationController.delegate = self
authorizationController.performRequests()
self.authorizationController = authorizationController
}
// Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
private func randomNonceString(length: Int = 32) -> String {
precondition(length > 0)
let charset: [Character] = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
var result = ""
var remainingLength = length
while remainingLength > 0 {
let randoms: [UInt8] = (0 ..< 16).map { _ in
var random: UInt8 = 0
let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
guard errorCode == errSecSuccess else {
fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
}
return random
}
randoms.forEach { random in
if remainingLength == 0 {
return
}
if random < charset.count {
result.append(charset[Int(random)])
remainingLength -= 1
}
}
}
return result
}
}
extension AppleSignInProvider: ASAuthorizationControllerDelegate {
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
do {
guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential else {
throw AuthError.credential
}
guard let nonce = currentNonce else {
throw AuthError.nonce
}
guard let appleIDToken = appleIDCredential.identityToken else {
throw AuthError.identityToken
}
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
throw AuthError.identityTokenString
}
let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)
completion(.success(credential))
} catch {
completion(.failure(error))
}
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
completion(.failure(error))
}
}
My delegate methods are called when the view controller is set as delegate, but that is not a fix for my issue.
Hey! I have been trying the last few days to discover devices in my network using NWConnection and NWConnectionGroup by sending a SSDP packet to 239.255.255.250 on port 1900 (by definition of SSDP?). I already have the multicast entitlement but that made no difference. Here are the two approaches I have tried:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
let params: NWParameters = .udp
params.allowLocalEndpointReuse = true
let connection = NWConnection(host: "239.255.255.250", port: 1_900, using: params)
connection.stateUpdateHandler = { [weak viewController = self] state in
guard let viewController = viewController else {
return
}
switch state {
case .ready:
viewController.send(to: connection)
default: return
}
}
connection.receiveMessage { (data, context, isComplete, errir) in
if let data = data {
let dataString = String(data: data, encoding: .utf8)
print(dataString ?? "", isComplete)
} else {
print(data ?? "", isComplete)
}
}
connection.start(queue: .main)
}
private func send(to connection: NWConnection) {
let message = "M-SEARCH * HTTP/1.1\r\nSt: ssdp:all\r\nHost: 239.255.255.250:1900\r\nMan: \"ssdp:discover\"\r\nMx: 1\r\n\r\n"
let payload = message.data(using: .utf8)
connection.send(content: payload, completion: .contentProcessed { (error) in
if let error = error {
print(error.localizedDescription)
} else {
print("ok")
}
})
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
do {
try setupConnection()
} catch {
print(error.localizedDescription)
}
}
private func setupConnection() throws {
let endpoints: [NWEndpoint] = [
.hostPort(host: "239.255.255.250", port: 1_900)
]
let params: NWParameters = .udp
params.allowLocalEndpointReuse = true
let multicast = try NWMulticastGroup(for: endpoints)
let group = NWConnectionGroup(with: multicast, using: params)
group.setReceiveHandler { (message, data, isComplete) in
if let data = data {
let dataString = String(data: data, encoding: .utf8)
print(message, dataString ?? "", isComplete)
} else {
print(message, data ?? "", isComplete)
}
}
group.stateUpdateHandler = { [weak viewController = self] (state) in
guard let viewController = viewController else {
return
}
switch state {
case .ready:
viewController.send(to: group)
default: return
}
}
group.start(queue: .main)
}
private func send(to group: NWConnectionGroup) {
let message = "M-SEARCH * HTTP/1.1\r\nST: ssdp:all\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 1\r\n\r\n"
let payload = message.data(using: .utf8)
group.send(content: payload) { error in
if let error = error {
print(error.localizedDescription)
} else {
print("ok")
}
}
}
}
I hope to get some help here as I couldn't find any working examples online. Thanks in advance!