Posts

Post not yet marked as solved
7 Replies
6.3k Views
I don't know what could be wrong but my UNNotificationServiceExtension is never getting called by any push from FCM. I call the FCM from a Python3 script and so far it works (I get a push notification but always with the default text and not the modified one). firebaseHeaders = { "Content-Type":"application/json", "Authorization":"key=MYKEY" } firebaseBody = { "to":devicetoken, "priority":"high", "mutable-content":True, "apns-priority":5, "notification": { "titlelockey":"push.goalReachedTitle", "bodylockey":"push.goalReachedContentRemote", "bodylocargs":[str(entry['value']), entry['region']], "sound":"default", "badge":1 }, "data": { "values":data, "region":entry['region'], "value":entry['value'] } } firebaseResult = requests.post("https://fcm.googleapis.com/fcm/send", data=None, json=firebaseBody, headers=firebaseHeaders) My Extension is also pretty basic (for testing) and I already tried to remove it and add it again to my main app project without success. class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent { bestAttemptContent.title = bestAttemptContent.title + " [TEST 123]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } } Anyone has a idea what I still can check, test or miss?
Posted Last updated
.
Post not yet marked as solved
0 Replies
405 Views
Is there any way to prevent the CKSubscription from getting invoked if the change that invoked it comes from this app instance? My app updates the CloudKit after every change but if the user does this changes quickly, there is a high chance that the subscription get back to me with outdated data even tho this change came from this very app instance. I still want this update to happen if these changes are done from a different app instance on another device or what so ever.
Posted Last updated
.
Post not yet marked as solved
15 Replies
4.2k Views
About 15 hours now since my customers start getting the error "Asset URL has expired" when they try to download any On-Demand Resource on any of my apps. It has worked before and it still works fine in TestFlight (with the same App versions). How do I get this fixed? Or what do I have todo now??
Posted Last updated
.
Post not yet marked as solved
4 Replies
2.5k Views
I tried now two different approaches (MCAdvertiserAssistant / MCBrowserViewController and MCNearbyServiceAdvertiser / MCNearbyServiceBrowser) to implement this in my first Swift app but always got the result that it stays at "Connecting" for a few seconds and than just declines the request. In a video from Hacking with Swift there was a popup if the connection should be accepted - this never comes up on my devices. So maybe this is the error already? As for the browser part, I use this ViewController wrapper to make it available: import MultipeerConnectivity import SwiftUI struct MultipeerConnectivityBrowserView: UIViewControllerRepresentable {   func makeUIViewController(context: UIViewControllerRepresentableContext<MultipeerConnectivityBrowserView>) -> MCBrowserViewController {     let service = MultipeerConnectivityService.instance()     guard let session = service.session else {       print("Failed to load MCSession for Browser")       return MCBrowserViewController()     }           let viewController = MCBrowserViewController(serviceType: service.serviceType, session: session)     viewController.delegate = service           return viewController   }   func updateUIViewController(_ uiViewController: MCBrowserViewController, context: UIViewControllerRepresentableContext<MultipeerConnectivityBrowserView>) {   } } struct MultipeerConnectivityBrowserView_Previews: PreviewProvider {   static var previews: some View {     MultipeerConnectivityBrowserView()   } } I can see my 2nd device in the upcoming dialog but when I click on it, as described above, it just hangs at "Connecting" until it, as it seems to me, timed out. This is currently the main implementation for the MC in my app: import MultipeerConnectivity class MultipeerConnectivityService: NSObject, MCSessionDelegate, MCBrowserViewControllerDelegate, MCAdvertiserAssistantDelegate { 		private static var internalInstance: MultipeerConnectivityService? = nil 		 		let serviceType = "sn-dueladviser" 		let peerID = MCPeerID(displayName: UIDevice.current.name) 		 		var session: MCSession? 		var advertiserAssistant: MCAdvertiserAssistant? 		 		static func instance() -> MultipeerConnectivityService { 				if let instance = internalInstance { 						return instance 				} 				 				internalInstance = MultipeerConnectivityService() 				return internalInstance! 		} 		 		private override init() { 				super.init() 				 				session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required) 				session?.delegate = self 		} 		 		func startHosting() { 				guard let session = session else { return } 				advertiserAssistant = MCAdvertiserAssistant(serviceType: serviceType, discoveryInfo: nil, session: session) 				advertiserAssistant?.delegate = self 				 				advertiserAssistant?.start() 		} 		 		func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) { 				 		} 		 		func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) { 				 		} 		 		func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) { 				 		} 		 		func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) { 				browserViewController.dismiss(animated: true, completion: { }) 		} 		 		func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) { 				browserViewController.dismiss(animated: true, completion: { }) 		} 		 		func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) { 				switch state { 				case .connected: 						print("Connected: \(peerID.displayName)") 				case .connecting: 						print("Connecting: \(peerID.displayName)") 				case .notConnected: 						print("Not Connected: \(peerID.displayName)") 						 				@unknown default: 						print("Unknown state received: \(peerID.displayName)") 				} 		} 		 		func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) { 				//todo: Receive data 		} } I tried to add NSLocalNetworkUsageDescription and NSBonjourServices without any change (even if both are not mentioned in any guides except the official documentation). Sadly it didn't change anything + it seems like my XCode does not know these keys or at least do not replace the key name with another text like it did with other keys like camera permission.
Posted Last updated
.
Post marked as solved
5 Replies
14k Views
Is there any way for us developers to refund In-App-Purchases to users? At the Google Play Store it is possible through the order management (see: https://i.imgur.com/FhhYAEu.png) but I can't find anything like that on ITC.
Posted Last updated
.
Post not yet marked as solved
0 Replies
1.3k Views
Is there a way to get the size inside a UIViewControllerRepresentable? I try to include a UIKit control that requires me to put the size in it's constructor. This is my code so far: final class ChartVC: UIViewControllerRepresentable {       func makeUIViewController(context: Context) -> UIViewController {     let viewController = UIViewController()           let chart = Chart(frame: CGRect(x: 0, y: 0, width: 300, height: 200)) //todo: don't use fixed values here...           viewController.view.addSubview(chart)     return viewController   }       func updateUIViewController(_ uiViewController: UIViewController, context: Context) { } } And this is, how I currently use this: ChartVC()   .frame(minWidth: 180, idealWidth: 280, maxWidth: 420, minHeight: 300, alignment: .center)   .padding()   .background(Color.contentBackgroundColor)   .cornerRadius(8) Question now is, how do I get the size that SwiftUI will apply to my frame?
Posted Last updated
.
Post not yet marked as solved
3 Replies
993 Views
After updating my Xcode to 12.0, all iOS 13 simulators are gone and there are also no iOS 14 simulators at all. Also I can't create any. Is there a way to fix this? Edit: I already tried to reinstall Xcode. Strange that the Xcode 12 beta worked good next to the Xcode 11.x installation...
Posted Last updated
.
Post not yet marked as solved
0 Replies
484 Views
I want to create a app that has to load data from my API on a regular basis. The data is changed every 15 minutes so I would like to use a similar interval to load my data to update my widget and the data in the app. But what is the proper way of implementing such behavior? I mean the app would need to update the data even when the app is closed in the app switcher to update the widget and so on. Background fetch seems to be the wrong way to me, and I'm also not sure about BGTaskScheduler. As far as I understand this, both needs to be started from my app which may not be opened after a device reboot. I'm sure there must be a way to implement the wanted behavior because mail apps need todo the very same on servers that do not support push.
Posted Last updated
.
Post not yet marked as solved
0 Replies
475 Views
How do I specify which indentifier from the com.apple.developer.icloud-container-identifiers Entitlements.plist entry to use with NSUbiquitousKeyValueStore? I know how to use a specific com.apple.security.application-groups with NSUserDefaults but couldn't find a way to do the same with NSUbiquitousKeyValueStore. I would like to port my code that currently works with NSUserDefaults to NSUbiquitousKeyValueStore to a shared identifier across my apps.
Posted Last updated
.
Post not yet marked as solved
0 Replies
547 Views
Is it possible to add WidgetKit only for iOS 14 devices while the same app has a TodayExtension for older iOS versions? Or does including WidgetKit increase the required OS version immediately to iOS 14? I would like to support at least iOS 13 as well with my app (better iOS 12 as well) but I'm also interested in adding WidgetKit for iOS 14 to my app. On my first app, I already had to learn that including VisionKit increased the minimum OS version to 13 so I would like to prevent this from happening in the plan phase already for my next project.
Posted Last updated
.
Post not yet marked as solved
0 Replies
482 Views
On some devices (like iPhone 8+ and iPhone 11 Pro Max) my text inside a Text element is getting trimmed even if there is enough space left. I have placed my Text like this: HStack { 		Spacer() 		 		Text(result.number) 				.font(.headline) 				.foregroundColor(Color.white) 				.padding(12) 				.frame(maxWidth: .infinity) 		 		Spacer() } But even a small text like "00000000" is getting trimmed way too early. What makes me wonder is, that the very same text works fine on a smaller device like the iPhone 11 or SE. For me it looks like that the Spacer take way more space as it should. So whats wrong here?
Posted Last updated
.
Post marked as solved
3 Replies
2.7k Views
I think I messed something up because except the default values, I cannot see anything in my list. I want to have a TextField and a "Counter" in my list per entry which should be editable the whole time. But also the preview just yields the default values and not the ones I set preemptively in my preview construct. Changes in runtime are just ignored. This is what I got so far, did I maybe messed up @State, @Binding and @ObservedObject again? Or did I missed something else? If I search for edit in swiftui list all I get is the EditButton solution which is not what I want. Sourcecode - https://developer.apple.com/forums/content/attachment/70b85477-f66c-4423-90bf-a1d073c2646c
Posted Last updated
.
Post marked as solved
2 Replies
697 Views
I just started with Swift a few days ago, so sorry if this question is kinda simple but I was not able to find a matching answer on Google for it. I want to implement a number that is "slowly" running down on a change. I want this number always to reach it's goal within a second no matter if it runs from 1000 to 100 or 110 to 100. But as of now, the UI always just takes the first change and not the following changes (I see different print outputs with the proper values but the actual UI does not update). This is how my model currently looks like: import SwiftUI class Player: Identifiable {   let id = UUID()          @Published var name: String        @Published var maximumLifePoints: Int   @Published var currentLifePoints: Int {     didSet {       currentProgress = 1.0 / Float(maximumLifePoints) * Float(currentLifePoints)     }   }       @Published var currentProgress: Float = 1       init(name: String, startLifePoints: Int) {     self.name = name           self.maximumLifePoints = startLifePoints     self.currentLifePoints = startLifePoints   }       func setCurrentLifePoints(lifePoints: Int) {     let difference = currentLifePoints - lifePoints     let differencePerStep = difference / 100           print("Diffrence: \(difference)")     print("Diffrence step: \(differencePerStep)")           let timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { timer in       self.currentLifePoints -= differencePerStep       print("Current life points: \(self.currentLifePoints)")     }           timer.fire()     DispatchQueue.main.asyncAfter(deadline: .now() + 0.99) {       timer.invalidate()       self.currentLifePoints = lifePoints       print("Final life points: \(self.currentLifePoints)")     }   } } This is my control which displays the "life points": import SwiftUI struct LiveCounter: View {		 		@State var player: Player 		 		var body: some View { 				GeometryReader { g in 						VStack (alignment: .center, spacing: 25.0) { 								ZStack { 										Circle() 												.fill(Color.offColor) 												.frame(width: self.circleSize(g.size), height: self.circleSize(g.size), alignment: .center) 										 										ProgressBar(currentValue: self.$player.currentProgress) 												.frame(width: self.circleSize(g.size), height: self.circleSize(g.size), alignment: .center) 										 										VStack (spacing: -4) { 												Text(self.player.name) 														.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.04 : g.size.height * 0.04)) 														.fontWeight(.bold) 														.foregroundColor(Color.textDefaultColor) 												 												Text("\(self.player.currentLifePoints.formattedWithSeparator)") 														.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.1 : g.size.height * 0.1)) 														.fontWeight(.black) 														.foregroundColor(Color.textDefaultColor) 												 												//Spacing to have life points still in center 												Text(" ") 														.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.04 : g.size.height * 0.04)) 														.fontWeight(.bold) 										} 								} 						} 				} 		} 		 		private func circleSize(_ size: CGSize) -> CGFloat? { 				return size.height > size.width ? size.width * 0.5 : size.height * 0.5 		} } So what did I miss to let the UI update to each change? I think I also messed up the Text(self.player.name) because this one does also not update on a change from another View. But for that problem I still have a few ideas how I can fix it not like with the async update stuff..
Posted Last updated
.
Post not yet marked as solved
2 Replies
2.1k Views
I hope this was the right sub forum for this question.Is there anywhere some documentation on how to support the dark theme with today widgets? My app supported theming before and it was easy to implement a switch for the theme in it throughtraitCollection.userInterfaceStylewhich is also available within the today widget (or at least it seems so). But how can we set the today widget background based on that? Or is there some flag to show that the widget is ready for the dark theme so that the OS will handle this on it's own?
Posted Last updated
.
Post not yet marked as solved
0 Replies
766 Views
Based on this posting from Apple: Offering Subscriptions to Multiple Apps, it should be possible to offer a single subscription to unlock multiple apps. So far, so good. But how do I need to set this up? Based on client request I want to setup the following structure:1. Auto-Renewable Subscription to cover all apps from this client2. Auto-Renewable Subscription to cover a portion of app from this client (optional, would be nice but the client would be happy with option 1 + 3 already if this is forbidden by Apple)3. Option to unlock each app on it's own with a single purchase (non-consumeable)But every time when I submit the app to the app store it is declined and I get a message pointing to this: App Store Review Guidelines - 3.1.2 Subscriptions But why is this when this is a normal option offered from Apple? Based on the only response I got from Apple I think there should be not a subscription when it is purchaseable as non-consumeable but that is only partial true because the non-consumeable unlocks only the current app while the subscription unlocks multiple apps. So what am I missing? All apps are designed that the user gets a warning when he tries to make a subscription if any app is already unlocked through a non-consumeable (because it would reduce the value of the subscription) and as soon as a subscription is active it is no longer possible to purchase any non-consumeable or subscription (except switching to another subscription tier if option 1 + 2 is possible in combination).
Posted Last updated
.