Posts under App & System Services topic

Post

Replies

Boosts

Views

Activity

StoreKit2 AppTransaction originalPurchaseVersion
I am looking to move from paid app to fremium without upsetting my existing users. I see WWDC2022 session where new fields introduced in iOS 16 are used to extract original application version user used to purchase the app. While my app supports iOS 14 and above, I am willing to sacrifice iOS 14 and go iOS 15 and above as StoreKit2 requires iOS 15 at the minimum. The code below is however only valid for iOS 16. I need to know what is the best way out for iOS 15 devices if I am using StoreKit2? If it is not possible in StoreKit2, then how much is the work involved in original StoreKit API(because in that case I can handle for iOS 14 as well)?
1
0
656
Jul ’23
Push payload is not present on notification tap
I am checking if the user taps on the firebase push notification and get the payload. override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo os_log("notification tapped %{public}@", log: OSLog.push, type: .info, userInfo) handleNotificationPayload(userInfo as! [String: AnyObject]) setFlutterLinkClickedVariable() } My use case is in app terminated state when push notification is tapped, get the link from payload and navigate to corresponding screen based on the link. This is working when there is only one push notification. When there are multiple push notifications with different links in the payload, only the first notification I tap works. Rest of the notifications just launches the app and does not navigate because the link is not set. I am getting the link from the payload and invoking flutter code which sets the link in the user defaults (shared preferences) and when the app launches in the home screen it checks for this variable and navigates accordingly. func handleNotificationPayload(_ payload: [String: AnyObject]) { if let link = payload["link"] as? String { setFlutterLinkVariable(link) } } override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { os_log("app did receive remote notification %{public}@", log: OSLog.push, type: .info, userInfo) handleNotificationPayload(userInfo as! [String : AnyObject]) completionHandler(.newData) } Currently when there is only one push notification it works because the link is set from the above method. The click delegate is not calling. I did set the delegate in application(:didFinishLaunchingWithOptions). UNUserNotificationCenter.current().delegate = self application.registerForRemoteNotifications() How to solve this issue? Thanks.
2
0
717
Jul ’23
Transaction.currentEntitlements is not consistent
I've recently published an app, and while developing it, I could always get consistent entitlements from Transaction.currentEntitlements. But now I see some inconsistent behaviour for a subscribed device in the AppStore version. It looks like sometimes the entitlements do not emit value for the subscriptions. It usually happens on the first couple tries when the device goes offline, or on the first couple tries when the device goes online. But it also happens randomly at other times as well. Can there be a problem with Transaction.currentEntitlements when the connectivity was just changed? Of course my implementation may also be broken. I will give you the details of my implementation below. I have a SubscriptionManager that is observable (irrelevant parts of the entity is omitted): final class SubscriptionManager: NSObject, ObservableObject { private let productIds = ["yearly", "monthly"] private(set) var purchasedProductIDs = Set<String>() var hasUnlockedPro: Bool { return !self.purchasedProductIDs.isEmpty } @MainActor func updatePurchasedProducts() async { var purchasedProductIDs = Set<String>() for await result in Transaction.currentEntitlements { guard case .verified(let transaction) = result else { continue } if transaction.revocationDate == nil { purchasedProductIDs.insert(transaction.productID) } else { purchasedProductIDs.remove(transaction.productID) } } // only update if changed to avoid unnecessary published triggers if purchasedProductIDs != self.purchasedProductIDs { self.purchasedProductIDs = purchasedProductIDs } } } And I call the updatePurchasedProducts() when the app first launches in AppDelegate, before returning true on didFinishLaunchingWithOptions as: Task(priority: .high) { await DependencyContainer.shared.subscriptionManager.updatePurchasedProducts() } You may be wondering maybe the request is not finished yet and I fail to refresh my UI, but it is not the case. Because later on, every time I do something related to a subscribed content, I check the hasUnlockedPro computed property of the subscription manager, which still returns false, meaning the purchasedProductIDs is empty. You may also be curious about the dependency container approach, but I ensured by testing multiple times that there is only one instance of the SubscriptionManager at all times in the app. Which makes me think maybe there is something wrong with Transaction.currentEntitlements I would appreciate any help regarding this problem, or would like to know if anyone else experienced similar problems.
6
6
2.8k
Jul ’23
Apple Pay Web Merchant Registration Authentication Requirements
I am trying to do a mass enablement of a merchant ids for a psp. The ids have been approved by apple. I am attempting to add more using the Post Request: https://apple-pay-gateway.apple.com/paymentservices/registerMerchant (https://developer.apple.com/documentation/applepaywebmerchantregistrationapi/register_merchant) but am always getting a Refuse to connect error. What authentication is required to get a 200 successful response?
1
0
779
Jul ’23
Extra-ordinary Networking
Most apps perform ordinary network operations, like fetching an HTTP resource with URLSession and opening a TCP connection to a mail server with Network framework. These operations are not without their challenges, but they’re the well-trodden path. If your app performs ordinary networking, see TN3151 Choosing the right networking API for recommendations as to where to start. Some apps have extra-ordinary networking requirements. For example, apps that: Help the user configure a Wi-Fi accessory Require a connection to run over a specific interface Listen for incoming connections Building such an app is tricky because: Networking is hard in general. Apple devices support very dynamic networking, and your app has to work well in whatever environment it’s running in. Documentation for the APIs you need is tucked away in man pages and doc comments. In many cases you have to assemble these APIs in creative ways. If you’re developing an app with extra-ordinary networking requirements, this post is for you. Note If you have questions or comments about any of the topics discussed here, put them in a new thread here on DevForums. Make sure I see it by putting it in the App & System Services > Networking area. And feel free to add tags appropriate to the specific technology you’re using, like Foundation, CFNetwork, Network, or Network Extension. Links, Links, and More Links Each topic is covered in a separate post: The iOS Wi-Fi Lifecycle describes how iOS joins and leaves Wi-Fi networks. Understanding this is especially important if you’re building an app that works with a Wi-Fi accessory. Network Interface Concepts explains how Apple platforms manage network interfaces. If you’ve got this far, you definitely want to read this. Network Interface Techniques offers a high-level overview of some of the more common techniques you need when working with network interfaces. Network Interface APIs describes APIs and core techniques for working with network interfaces. It’s referenced by many other posts. Running an HTTP Request over WWAN explains why most apps should not force an HTTP request to run over WWAN, what they should do instead, and what to do if you really need that behaviour. If you’re building an iOS app with an embedded network server, see Showing Connection Information in an iOS Server for details on how to get the information to show to your user so they can connect to your server. Many folks run into trouble when they try to find the device’s IP address, or other seemingly simple things, like the name of the Wi-Fi interface. Don’t Try to Get the Device’s IP Address explains why these problems are hard, and offers alternative approaches that function correctly in all network environments. Similarly, folks also run into trouble when trying to get the host name. On Host Names explains why that’s more complex than you might think. If you’re working with broadcasts or multicasts, see Broadcasts and Multicasts, Hints and Tips. If you’re building an app that works with a Wi-Fi accessory, see Working with a Wi-Fi Accessory. If you’re trying to gather network interface statistics, see Network Interface Statistics. There are also some posts that are not part of this series but likely to be of interest if you’re working in this space: TN3179 Understanding local network privacy discusses the local network privacy feature. Calling BSD Sockets from Swift does what it says on the tin, that is, explains how to call BSD Sockets from Swift. When doing weird things with the network, you often find yourself having to use BSD Sockets, and that API is not easy to call from Swift. The code therein is primarily for the benefit of test projects, oh, and DevForums posts like these. TN3111 iOS Wi-Fi API overview is a critical resource if you’re doing Wi-Fi specific stuff on iOS. TLS For Accessory Developers tackles the tricky topic of how to communicate securely with a network-based accessory. A Peek Behind the NECP Curtain discusses NECP, a subsystem that control which programs have access to which network interfaces. Networking Resources has links to many other useful resources. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Revision History 2025-07-31 Added a link to A Peek Behind the NECP Curtain. 2025-03-28 Added a link to On Host Names. 2025-01-16 Added a link to Broadcasts and Multicasts, Hints and Tips. Updated the local network privacy link to point to TN3179. Made other minor editorial changes. 2024-04-30 Added a link to Network Interface Statistics. 2023-09-14 Added a link to TLS For Accessory Developers. 2023-07-23 First posted.
0
0
5k
Jul ’23
Working with a Wi-Fi Accessory
For important background information, read Extra-ordinary Networking before reading this. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Working with a Wi-Fi Accessory Building an app that works with a Wi-Fi accessory presents specific challenges. This post discusses those challenges and some recommendations for how to address them. Note While my focus here is iOS, much of the info in this post applies to all Apple platforms. IMPORTANT iOS 18 introduced AccessorySetupKit, a framework to simplify the discovery and configuration of an accessory. I’m not fully up to speed on that framework myself, but I encourage you to watch WWDC 2024 Session 10203 Meet AccessorySetupKit and read the framework documentation. IMPORTANT iOS 26 beta introduced WiFiAware, a framework for setting up communication with Wi-Fi Aware accessories. Wi-Fi Aware is an industry standard to securely discover, pair, and communicate with nearby devices. This is especially useful for stand-alone accessories (defined below). For more on this framework, watch WWDC 2025 Session 228 Supercharge device connectivity with Wi-Fi Aware and read the framework documentation. Accessory Categories I classify Wi-Fi accessories into three different categories. A bound accessory is ultimately intended to join the user’s Wi-Fi network. It may publish its own Wi-Fi network during the setup process, but the goal of that process is to get the accessory on to the existing network. Once that’s done, your app interacts with the accessory using ordinary networking APIs. An example of a bound accessory is a Wi-Fi capable printer. A stand-alone accessory publishes a Wi-Fi network at all times. An iOS device joins that network so that your app can interact with it. The accessory never provides access to the wider Internet. An example of a stand-alone accessory is a video camera that users take with them into the field. You might want to write an app that joins the camera’s network and downloads footage from it. A gateway accessory is one that publishes a Wi-Fi network that provides access to the wider Internet. Your app might need to interact with the accessory during the setup process, but after that it’s useful as is. An example of this is a Wi-Fi to WWAN gateway. Not all accessories fall neatly into these categories. Indeed, some accessories might fit into multiple categories, or transition between categories. Still, I’ve found these categories to be helpful when discussing various accessory integration challenges. Do You Control the Firmware? The key question here is Do you control the accessory’s firmware? If so, you have a bunch of extra options that will make your life easier. If not, you have to adapt to whatever the accessory’s current firmware does. Simple Improvements If you do control the firmware, I strongly encourage you to: Support IPv6 Implement Bonjour [1] These two things are quite easy to do — most embedded platforms support them directly, so it’s just a question of turning them on — and they will make your life significantly easier: Link-local addresses are intrinsic to IPv6, and IPv6 is intrinsic to Apple platforms. If your accessory supports IPv6, you’ll always be able to communicate with it, regardless of how messed up the IPv4 configuration gets. Similarly, if you support Bonjour, you’ll always be able to find your accessory on the network. [1] Bonjour is an Apple term for three Internet standards: RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses RFC 6762 Multicast DNS RFC 6763 DNS-Based Service Discovery WAC For a bound accessory, support Wireless Accessory Configuration (WAC). This is a relatively big ask — supporting WAC requires you to join the MFi Program — but it has some huge benefits: You don’t need to write an app to configure your accessory. The user will be able to do it directly from Settings. If you do write an app, you can use the EAWiFiUnconfiguredAccessoryBrowser class to simplify your configuration process. HomeKit For a bound accessory that works in the user’s home, consider supporting HomeKit. This yields the same onboarding benefits as WAC, and many other benefits as well. Also, you can get started with the HomeKit Open Source Accessory Development Kit (ADK). Bluetooth LE If your accessory supports Bluetooth LE, think about how you can use that to improve your app’s user experience. For an example of that, see SSID Scanning, below. Claiming the Default Route, Or Not? If your accessory publishes a Wi-Fi network, a key design decision is whether to stand up enough infrastructure for an iOS device to make it the default route. IMPORTANT To learn more about how iOS makes the decision to switch the default route, see The iOS Wi-Fi Lifecycle and Network Interface Concepts. This decision has significant implications. If the accessory’s network becomes the default route, most network connections from iOS will be routed to your accessory. If it doesn’t provide a path to the wider Internet, those connections will fail. That includes connections made by your own app. Note It’s possible to get around this by forcing your network connections to run over WWAN. See Binding to an Interface in Network Interface Techniques and Running an HTTP Request over WWAN. Of course, this only works if the user has WWAN. It won’t help most iPad users, for example. OTOH, if your accessory’s network doesn’t become the default route, you’ll see other issues. iOS will not auto-join such a network so, if the user locks their device, they’ll have to manually join the network again. In my experience a lot of accessories choose to become the default route in situations where they shouldn’t. For example, a bound accessory is never going to be able to provide a path to the wider Internet so it probably shouldn’t become the default route. However, there are cases where it absolutely makes sense, the most obvious being that of a gateway accessory. Acting as a Captive Network, or Not? If your accessory becomes the default route you must then decide whether to act like a captive network or not. IMPORTANT To learn more about how iOS determines whether a network is captive, see The iOS Wi-Fi Lifecycle. For bound and stand-alone accessories, becoming a captive network is generally a bad idea. When the user joins your network, the captive network UI comes up and they have to successfully complete it to stay on the network. If they cancel out, iOS will leave the network. That makes it hard for the user to run your app while their iOS device is on your accessory’s network. In contrast, it’s more reasonable for a gateway accessory to act as a captive network. SSID Scanning Many developers think that TN3111 iOS Wi-Fi API overview is lying when it says: iOS does not have a general-purpose API for Wi-Fi scanning It is not. Many developers think that the Hotspot Helper API is a panacea that will fix all their Wi-Fi accessory integration issues, if only they could get the entitlement to use it. It will not. Note this comment in the official docs: NEHotspotHelper is only useful for hotspot integration. There are both technical and business restrictions that prevent it from being used for other tasks, such as accessory integration or Wi-Fi based location. Even if you had the entitlement you would run into these technical restrictions. The API was specifically designed to support hotspot navigation — in this context hotspots are “Wi-Fi networks where the user must interact with the network to gain access to the wider Internet” — and it does not give you access to on-demand real-time Wi-Fi scan results. Many developers look at another developer’s app, see that it’s displaying real-time Wi-Fi scan results, and think there’s some special deal with Apple that’ll make that work. There is not. In reality, Wi-Fi accessory developers have come up with a variety of creative approaches for this, including: If you have a bound accessory, you might add WAC support, which makes this whole issue go away. In many cases, you can avoid the need for Wi-Fi scan results by adopting AccessorySetupKit. You might build your accessory with a barcode containing the info required to join its network, and scan that from your app. This is the premise behind the Configuring a Wi-Fi Accessory to Join the User’s Network sample code. You might configure all your accessories to have a common SSID prefix, and then take advantage of the prefix support in NEHotspotConfigurationManager. See Programmatically Joining a Network, below. You might have your app talk to your accessory via some other means, like Bluetooth LE, and have the accessory scan for Wi-Fi networks and return the results. Programmatically Joining a Network Network Extension framework has an API, NEHotspotConfigurationManager, to programmatically join a network, either temporarily or as a known network that supports auto-join. For the details, see Wi-Fi Configuration. One feature that’s particularly useful is it’s prefix support, allowing you to create a configuration that’ll join any network with a specific prefix. See the init(ssidPrefix:) initialiser for the details. For examples of how to use this API, see: Configuring a Wi-Fi Accessory to Join the User’s Network — It shows all the steps for one approach for getting a non-WAC bound accessory on to the user’s network. NEHotspotConfiguration Sample — Use this to explore the API in general. Secure Communication Users expect all network communication to be done securely. For some ideas on how to set up a secure connection to an accessory, see TLS For Accessory Developers. Revision History 2025-06-19 Added a preliminary discussion of Wi-Fi Aware. 2024-09-12 Improved the discussion of AccessorySetupKit. 2024-07-16 Added a preliminary discussion of AccessorySetupKit. 2023-10-11 Added the HomeKit section. Fixed the link in Secure Communication to point to TLS For Accessory Developers. 2023-07-23 First posted.
0
0
1.6k
Jul ’23
Don’t Try to Get the Device’s IP Address
For important background information, read Extra-ordinary Networking before reading this. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Don’t Try to Get the Device’s IP Address I regularly see questions like: How do I find the IP address of the device? How do I find the IP address of the Wi-Fi interface? How do I identify the Wi-Fi interface? I also see a lot of really bad answers to these questions. That’s understandable, because the questions themselves don’t make sense. Networking on Apple platforms is complicated and many of the things that are ‘obviously’ true are, in fact, not true at all. For example: There’s no single IP address that represents the device, or an interface. A device can have 0 or more interfaces, each of which can have 0 or more IP addresses, each of which can be IPv4 and IPv6. A device can have multiple interfaces of a given type. It’s common for iPhones to have multiple WWAN interfaces, for example. It’s not possible to give a simple answer to any of these questions, because the correct answer depends on the context. Why do you need this particular information? What are you planning to do with it? This post describes the scenarios I most commonly encounter, with my advice on how to handle each scenario. IMPORTANT BSD interface names, like en0, are not considered API. There’s no guarantee, for example, that an iPhone’s Wi-Fi interface is en0. If you write code that relies on a hard-coded interface name, it will fail in some situations. Service Discovery Some folks want to identify the Wi-Fi interface so that they can run a custom service discovery protocol over it. Before you do that, I strongly recommend that you look at Bonjour. This has a bunch of advantages: It’s an industry standard [1]. It’s going to be more efficient on the ‘wire’. You don’t have to implement it yourself, you can just call an API [2]. For information about the APIs available, see TN3151 Choosing the right networking API. If you must implement your own service discovery protocol, don’t think in terms of finding the Wi-Fi interface. Rather, write your code to work with all Wi-Fi interfaces, or perhaps even all Ethernet-like interfaces. That’s what Apple’s Bonjour implementation does, and it means that things will work in odd situations [3]. To find all Wi-Fi interfaces, get the interface list and filter it for ones with the Wi-Fi functional type. To find all broadcast-capable interfaces, get the interface list and filter it for interfaces with the IFF_BROADCAST flag set. If the service you’re trying to discover only supports IPv4, filter out any IPv6-only interfaces. For advice on how to do this, see Interface List and Network Interface Type in Network Interface APIs. When working with multiple interfaces, it’s generally a good idea to create a socket per interface and then bind that socket to the interface. That ensures that, when you send a packet, it’ll definitely go out the interface you expect. For more information on how to implement broadcasts correctly, see Broadcasts and Multicasts, Hints and Tips. [1] Bonjour is an Apple term for: RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses RFC 6762 Multicast DNS RFC 6763 DNS-Based Service Discovery [2] That’s true even on non-Apple platforms. It’s even true on most embedded platforms. If you’re talking to a Wi-Fi accessory, see Working with a Wi-Fi Accessory. [3] Even if the service you’re trying to discover can only be found on Wi-Fi, it’s possible for a user to have their iPhone on an Ethernet that’s bridged to a Wi-Fi. Why on earth would they do that? Well, security, of course. Some organisations forbid their staff from using Wi-Fi. Logging and Diagnostics Some folks want to log the IP address of the Wi-Fi interface, or the WWAN, or both for diagnostic purposes. This is quite feasible, with the only caveat being there may be multiple interfaces of each type. To find all interfaces of a particular type, get the interface list and filter it for interfaces with that functional type. See Interface List and Network Interface Type in Network Interface APIs. Interface for an Outgoing Connection There are situations where you need to get the interface used by a particular connection. A classic example of that is FTP. When you set up a transfer in FTP, you start with a control connection to the FTP server. You then open a listener and send its IP address and port to the FTP server over your control connection. What IP address should you use? There’s an easy answer here: Use the local IP address for the control connection. That’s the one that the server is most likely to be able to connect to. To get the local address of a connection: In Network framework, first get the currentPath property and then get its localEndpoint property. In BSD Sockets, use getsockname. See its man page for details. Now, this isn’t a particularly realistic example. Most folks don’t use FTP these days [1] but, even if they do, they use FTP passive mode, which avoids the need for this technique. However, this sort of thing still does come up in practice. I recently encountered two different variants of the same problem: One developer was implementing VoIP software and needed to pass the devices IP address to their VoIP stack. The best IP address to use was the local IP address of their control connection to the VoIP server. A different developer was upgrading the firmware of an accessory. They do this by starting a server within their app and sending a command to the accessory to download the firmware from that server. Again, the best IP address to use is the local address of the control connection. [1] See the discussion in TN3151 Choosing the right networking API. Listening for Connections If you’re listening for incoming network connections, you don’t need to bind to a specific address. Rather, listen on all local addresses. In Network framework, this is the default for NWListener. In BSD Sockets, set the address to INADDR_ANY (IPv4) or in6addr_any (IPv6). If you only want to listen on a specific interface, don’t try to bind to that interface’s IP address. If you do that, things will go wrong if the interface’s IP address changes. Rather, bind to the interface itself: In Network framework, set either the requiredInterfaceType property or the requiredInterface property on the NWParameters you use to create your NWListener. In BSD Sockets, set the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket option. How do you work out what interface to use? The standard technique is to get the interface list and filter it for interfaces with the desired functional type. See Interface List and Network Interface Type in Network Interface APIs. Remember that their may be multiple interfaces of a given type. If you’re using BSD Sockets, where you can only bind to a single interface, you’ll need to create multiple listeners, one for each interface. Listener UI Some apps have an embedded network server and they want to populate a UI with information on how to connect to that server. This is a surprisingly tricky task to do correctly. For the details, see Showing Connection Information for a Local Server. Outgoing Connections In some situations you might want to force an outgoing connection to run over a specific interface. There are four common cases here: Set the local address of a connection [1]. Force a connection to run over a specific interface. Force a connection to run over a type of interface. Force a connection to run over an interface with specific characteristics. For example, you want to download some large resource without exhausting the user’s cellular data allowance. The last case should be the most common — see the Constraints section of Network Interface Techniques — but all four are useful in specific circumstances. The following sections explain how to tackle these tasks in the most common networking APIs. [1] This implicitly forces the connection to use the interface with that address. For an explanation as to why, see the discussion of scoped routing in Network Interface Techniques. Network Framework Network framework has good support for all of these cases. Set one or more of the following properties on the NWParameters object you use to create your NWConnection: requiredLocalEndpoint property requiredInterface property prohibitedInterfaces property requiredInterfaceType property prohibitedInterfaceTypes property prohibitConstrainedPaths property prohibitExpensivePaths property Foundation URL Loading System URLSession has fewer options than Network framework but they work in a similar way: Set one or more of the following properties on the URLSessionConfiguration object you use to create your session: allowsCellularAccess property allowsConstrainedNetworkAccess property allowsExpensiveNetworkAccess property Note While these session configuration properties are also available on URLRequest, it’s better to configure this on the session. There’s no option that forces a connection to run over a specific interface. In most cases you don’t need this — it’s better to use the allowsConstrainedNetworkAccess and allowsExpensiveNetworkAccess properties — but there are some situations where that’s necessary. For advice on this front, see Running an HTTP Request over WWAN. BSD Sockets BSD Sockets has very few options in this space. One thing that’s easy and obvious is setting the local address of a connection: Do that by passing the address to bind. Alternatively, to force a connection to run over a specific interface, set the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket options. Revision History 2025-01-21 Added a link to Broadcasts and Multicasts, Hints and Tips. Made other minor editorial changes. 2023-07-18 First posted.
0
0
2.3k
Jul ’23
Matter pairing without Matter client developer profile
To be able to paire a matter device on ios I need to installed on my iPhone the matter client developper profile as indicate on the apple documentation Adding Matter support to your ecosystem | Apple Developer Documentation (To test your app on the iOS or macOS device that initiates the pairing, download the developer profile now, then install it.) When I do that it works perfectly. Otherwise the documentation says that the profile is only needed for development but when I want to use my app from the apple store (validate by Apple) and when I remove the profile it doesn't work anymore. What do I have to do to paire Matter device on iphone without the Matter client developer profile.
13
2
2.8k
Jul ’23
Is wallet extension an mandatory implementation for Apple Pay and Add to wallet?
I am working on a banking application (includes iPhone and iPad) which includes add to wallet feature. During the implementation I saw one document it is mentioned that for iPad app, the app must be extended to support Apple pay functionality. Details from document says "Card Issuers with an iOS mobile banking app must support Card Issuer iOS Wallet extension functionality to enable Card issuer mobile app customers to provision new cards directly from the iOS Wallet app with all eligible Apple iOS devices. If the Card Issuer has a dedicated iPad App, that App must be extended to support Apple Pay functionality. " Is wallet extension implementation required for Apple pay to work in iPhone and iPad? Is wallet extension a mandatory implementation for Add to Apple Wallet feature to work and approved by Apple? I am little confused in this. Anyone who integrated Apple pay or done add to Apple Wallet feature recently without wallet extension faced any rejection? Any help would be much appreciated.
4
2
3.6k
Aug ’23
How to cancel a subscription made by user in the TestFlight?
when we test in app purchase feature in TestFlight, we realize that TestFlight using our real iCloud account in AppStore, but because the app installed from TestFlight, they know it is still "Testing Phase" so they purchase set to FREE. Now im asking about how to test in app purchase for CANCEL SUBSCRIPTION? I can't found in my real iCloud account, either for my sandbox account inside AppStore settings. Please any response will helpful. Thankyou.
1
2
1.2k
Aug ’23
Companion app can't be installed on iPhone for some users who have installed the watchOS only version app
Hello! I'm facing the following Appstore issue. There was an watchOS only app, without a companion app. In current 1.6 version the app has a companion app and it can be properly installed by new users from their iPhones or watches. Unfortunately, all old users, who have installed the app from their watches don't see a way to install the app from the Appstore (they can download the latest watchOS version though). Many things have been tried - uninstalling, installing on the watch. Looking for a purchase, removing subscription, but without luck. The Appstore shows "purchased" button instead "Get" or the cloud icon. Is this a bug in the Appstore or there is a way to recover from this edge case. Thanks, Emil
4
2
1.3k
Aug ’23
ApplePay how to create merchant tokens in sandbox
Hi, I'm trying to create merchant tokens in ApplePay sandbox environment, so then I can use them to invalidate token API call and lifecycle notifications testing. When processing test payment I use Apple Pay payment request taken directly from Apple's demo website (I skipped non important part of JSON) { ... "recurringPaymentRequest": { "paymentDescription": "A description of the recurring payment to display to the user in the payment sheet.", "regularBilling": { "label": "Recurring", "amount": "4.99", "paymentTiming": "recurring", "recurringPaymentStartDate": "2023-08-11T11:20:32.369Z" }, "trialBilling": { "label": "7 Day Trial", "amount": "0.00", "paymentTiming": "recurring", "recurringPaymentEndDate": "2023-08-11T11:20:32.369Z" }, "billingAgreement": "A localized billing agreement displayed to the user in the payment sheet prior to the payment authorization.", "managementURL": "https://applepaydemo.apple.com", "tokenNotificationURL": "https://applepaydemo.apple.com" }, ... } Payment is successful, but merchantTokenIdentifier in decrypted ApplePay token is always empty, regardless of test card used, I tried Visa, MasterCard, Amex. Anyone have an idea what I'm missing and how to get that merchant token? Is it even possible to test merchant tokens (lifecycle notifications) in sandbox?
3
3
1.3k
Aug ’23
How to get full raw data of barcode using AVFoundation framework
I am creating a barcode reader using the AVfoundation framework for iOS and IPadOS. The read result goes into payloadstringvalue, but I want to check the control characters contained in the symbol, so I am using the raw data of the description, which is a property of NSObjectProtocol inherited by VNBarcodeObservation. However, I noticed that if the length set in the raw data exceeds 26, some of the raw data in the description is omitted. So my question is, is it possible to set it so that all the raw data in the description is written out without omitting any raw data? If so, could you please tell me how to set this up? Also, if you know of any other way to extract the raw barcode data, I would appreciate it if you could let me know. Thank you.
1
0
584
Aug ’23
Background location stops with (kCLErrorDomain error 1.) but permission was granted
We are currently experiencing a very interesting issue when accessing the location in the background with CLLocationManager. The user has given our app the "whenInUse" permission for locations and in most cases the app provides location updates even when it's in the background. However, when we started to use other navigation apps in the foreground we saw that the func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) method was called with (kCLErrorDomain error 1.). The user hasn't changed the location permission and we saw that locations were delivered once the user opened the app again. I don't see anything in the documentation explaining this issue, but I chatted with other developers that confirm that specific behavior. Am I missing something here?
2
3
857
Aug ’23
Why Non-Consumable product has originalTransactionId?
I try to call Get Transaction Info from App Store Server API, and the transactionId is for a Non-consumable type product, but it is odd that there are so many different transactionId and they have a same originalTransactionId { "bundleId": "${bundleId}", "environment": "Production", "inAppOwnershipType": "PURCHASED", "originalPurchaseDate": 1691220528000, "originalTransactionId": "${originalTransactionId}", "productId": "${productId}", "purchaseDate": 1691220528000, "quantity": 1, "signedDate": 1692590989925, "storefront": "USA", "storefrontId": "143441", "transactionId": "${originalTransactionId}", "transactionReason": "PURCHASE", "type": "Non-Consumable" } the defination of Non-Consumable is can only purchase once for same apple account. But why there would have originalTransactionId?
3
0
1k
Aug ’23
What is the point of the Unified Logging System and the new `Logger` API if it's so inflexible and clumsy?
Hi there! Sorry in advance, this is going to be a long post of Apple developer pains which I want to share with you, and, hopefully, find the answer and help Apple become better. I'm at the very beginning of my new and exciting personal project which (I hope) may one day feed me and be my daily source of inspiration. I'm not a newbie in Apple development nor am I a senior-level developer — just a fellow developa'. Here's the problem I bring to you — why Apple promotes Unified Logging System and recommends using it as the primary way to implement logging in 3rd-party apps? No doubt, OSLog is a great, secure, efficient, and centralized way to gather diagnostics information, and I, starting my new project, am itching to choose exactly this 1st-party logging infrastructure. This decision in theory has a number of benefits: I don't have to depend on 3rd-party logging frameworks which may eventually be discontinued; I have extensive documentation, great WWDC sessions explaining how to use the framework, and stackoverflow answers from the whole Apple dev community in case I experience any troubles; I have this cool Console.app and upcoming Xcode 15 tools with great visualization and filtering of my logs; It's quite a robust and stable infrastructure which I may restfully rely on. But... the thing is there's this big elephant in the room — this API is non-customizable, inconvenient, and hard to use in terms of the app architecture. I can't write my own protocol wrapper around it to abstract my domain logic from implementation details or just simplify the usage at the call site. I can't configure my own format for log messages (this is debatable, since Console.app doesn't provide "naked strings" as Xcode 14 and earlier, but still). And what's most important — I can't conveniently retrieve the logs! I can't implement the functionality where my user just taps the button, and the logs are sent on the background queue to my support email (eskimo's answer). They would have to go through this monstrous procedure of holding volume buttons on the iPhone, connecting their device to the Mac, gathering sysdiagnose, entering some weird Terminal commands (jeez, these nerdy developers...), etc. If it ever succeeds, of course, and something doesn't go wrong, leaving my user angry and dissatisfied with my app. Regarding the protocol wrapper, I can't do something like this: protocol Logging { var logger: Logger { get } func info(_ message: OSLogMessage) } extension Logging { var logger: Logger { return Logger( subsystem: "com.my.bundle.id", category: String(describing: Self.self) ) } func info(_ message: OSLogMessage) { logger.info(message) } } class MyClass: Logging { func someImportantMethod() { // ... self.info("Some useful debug info: \(someVar, privacy: .public)") } } I've been investigating this topic for 2 days, and it's the farthest I want to go in beating my head over how to do two simple things: How to isolate logging framework implementation decision from my main code and write convenience wrappers? How to easily transfer the log files from the user to the developer? And I'm not the only one struggling. Here's just one example among hundreds of other questions that are being asked on dev forums: https://www.hackingwithswift.com/forums/ios/unified-logging-system-retrieve-logs-on-device/838. I've read almost all Apple docs which describe the modern Unified Logging System, I've read through eskimo's thread on Apple Developer Forum about the API, but I still haven't found the answer. Maybe, I've misperceived this framework and it's not the tool I'm searching for? Maybe, it focuses on different aspects of logging, e.g. signposting, rather than logging the current state of the app? What am I missing?
5
0
3.1k
Aug ’23
SwiftData does not work on a background Task even inside a custom ModelActor.
I have created an actor for the ModelContainer, in order to perform a data load when starting the app in the background. For this I have conformed to the ModelActor protocol and created the necessary elements, even preparing for test data. Then I create a function of type async throws to perform the database loading processes and everything works fine, in that the data is loaded and when loaded it is displayed reactively. actor Container: ModelActor { nonisolated let modelContainer: ModelContainer nonisolated let modelExecutor: ModelExecutor static let modelContainer: ModelContainer = { do { return try ModelContainer(for: Empleados.self) } catch { fatalError() } }() let context: ModelContext init(container: ModelContainer = Container.modelContainer) { self.modelContainer = container let context = ModelContext(modelContainer) self.modelExecutor = DefaultSerialModelExecutor(modelContext: context) self.context = context Task { do { try await loadData() } catch { print("Error en la carga \(error)") } } } } The problem is that, in spite of doing the load inside a Task and that there is no problem, when starting the app it stops responding the UI while loading to the user interactions. Which gives me to understand that actually the task that should be in a background thread is running somehow over the MainActor. As I have my own API that will provide the information to my app and refresh it at each startup or even send them in Batch when the internet connection is lost and comes back, I don't want the user to be continuously noticing that the app stops because it is performing a heavy process that is not really running in the background. Tested and compiled on Xcode 15 beta 7. I made a Feedback for this: FB13038621. Thanks Julio César
8
1
9k
Aug ’23
Application already supports iMessage Extension can not appear in Stickers on iOS 17.0
Our application already supports an iMessage Extension, allowing users to create and send custom or trending stickers. On iOS 17.0, a popup menu replaces the old tab in iMessage with a "Stickers" option, and iMessage extensions are put in the "More" option. The "Stickers" page only shows the Sticker Pack Extension. However, an application can only support Sticker Pack Extension or iMessage Extension. Get this error: "Multiple message payload provider extensions found in app but only one is allowed". Is there any workaround here? We want our application to keep the iMessage extension but also provide sticker packs.
1
2
634
Aug ’23
Interactive Widget: unable to reload timeline from AppIntent
My app features two kinds of widgets, let's call them kind A and kind B. I have both A and B widgets on my Home Screen. When I tap the button on widget A (associated with App Intent), I expect widget B to also reload. However, if you call WidgetCenter.shared.reloadAllTimelines() inside the perform() method of the AppIntent, the timeline of widget B does not reload immediately. This issue only occurs on a physical device and is not consistently reproducible. On a simulator, however, widget B reloads as expected. FB13152293
5
4
1.2k
Sep ’23