Posts

Post not yet marked as solved
1 Replies
2.1k Views
Xcode's fix-its like to insert code like this: if #available(iOSApplicationExtension 15.0, *) { // Use some iOS 15 API here. } Usually, I just change those to this: if #available(iOS 15.0, *) { // Use some iOS 15 API here. } It's not clear to me, though, what the difference between the two is. Is iOSApplicationExtension more or less restrictive than iOS? Are there APIs that you could only call within the first block above? There are some APIs that are marked unavailable in extensions, but they don't seem to be affected by this attribute. This, for example, compiles just fine: if #available(iOSApplicationExtension 15.0, *) { // This is marked NS_EXTENSION_UNAVAILABLE_IOS print(UIApplication.shared) } So what's the difference?
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
0 Replies
453 Views
The WeatherKit REST API returns different weather objects for different data sets (currentWeather, forecastDaily, forecastHourly, etc.) . Via the REST API, I can request the "current" weather for any given date, using the currentAsOf query parameter. However, in the native WeatherKit framework, I don't see any way to get a "CurrentWeather" object for a past date, even though this appears to be possible via the REST API. So if I want to know what the temperature was at 10:30am yesterday, for example, the best I can do with the native framework is request the hourly weather for 10:00am and 11:00am yesterday, and then average the two. But if I use the REST API, I could query that directly. Is this correct? Is there no way to get "current" weather conditions for past dates? (Or, alternatively, is currentAsOf not actually doing what I think it's doing?)
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
0 Replies
1.1k Views
Xcode 14 no longer supports bitcode. The release notes say this: Starting with Xcode 14, bitcode is no longer required for watchOS and tvOS applications, and the App Store no longer accepts bitcode submissions from Xcode 14. Xcode no longer builds bitcode by default and generates a warning message if a project explicitly enables bitcode: “Building with bitcode is deprecated. Please update your project and/or target settings to disable bitcode.” The capability to build with bitcode will be removed in a future Xcode release. IPAs that contain bitcode will have the bitcode stripped before being submitted to the App Store. Debug symbols for past bitcode submissions remain available for download. (86118779) However, as I understand it, Xcode 13 still requires bitcode for Apple Watch targets. I'm trying to clean up warnings when building with Xcode 14 betas, so that we can really try it out during the beta period. However, I'm concerned that if I disable bitcode for the Apple Watch targets, it will either fail to build in Xcode 13, or it will get rejected by App Store Connect. Is there a way to disable bitcode when building under Xcode 14 without causing problems in Xcode 13?
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
2 Replies
1.2k Views
The WWDC 2021 CloudKit session talked about the new encryptedValues field on CKRecord. It also indicated that CKAssets have already been end-to-end encrypted in previous releases. The documentation indicates that for encrypted values such as these: CloudKit encrypts the fields’ values on-device before saving them to iCloud, and decrypts the values only after fetching them from the server. The encryption keys are available exclusively to the record’s owner and, if the user shares the record, that share’s participants. For a client that is accessing CloudKit via the HTTP interface, the documentation indicates that assets have a downloadURL property which can be used to fetch the asset. Does this URL download the already-decrypted asset? Or does it need to be encrypted after downloading? If the asset is already decrypted at the time it is downloaded, how can this work, since as I understand it the key should not even be available to Apple. If the asset is not decrypted at that point, is there documentation about how we need to decrypt it?
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
0 Replies
741 Views
I have an app that deploys back to macOS 10.13. It also uses code from Network.framework, which was introduced in macOS 10.14. In code, I use import Network to import the framework. Because the framework is not available on our oldest deployment target, I'm also adding -weak_framework Network to our Other Linker Flags. This builds and runs just fine. However, upon inspecting the actual binary with otool -L, it appears that the app is trying to link to /System/Library/PrivateFrameworks/Network.framework instead of /System/Library/Frameworks/Network.framework. This results in a rejection from App Store review, because it detects that we're using private APIs. This seems like a bug in the linker, and I've filed FB9715763 accordingly. But in the meantime, I have an app to ship. Is there a way to tell the linker to use a particular path for this framework? I've tried adding /System/Library/Frameworks to Framework Search Paths, but that doesn't seem to be helping.
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
4 Replies
3.2k Views
I'm trying to get a persistent reference for a SecIdentityRef so I can reliably retrieve it later. I've tried a variety of things in the query parameter of SecItemCopyMatching, but I can't get it to work. I know the item exists in the keychain; I just barely called SecItemAdd not long ago. Here's what I've got right now:let identityArray: CFArray = [identity] as CFArray let query: [CFString: AnyObject] = [kSecClass: kSecClassIdentity, kSecMatchItemList: identityArray, kSecReturnPersistentRef: true] var _persistentItems: AnyObject? let copyResult = SecItemCopyMatching(query, &_persistentItems) // copyResult is -50 (errSecParam)I've tried the following other queries as well:let query = [kSecMatchItemList: selfArray, kSecReturnPersistentRef: true] // Produces -50 (errSecParam)let query = [kSecClass: kSecClassIdentity, kSecValueRef: identity, kSecReturnPersistentRef: true] // Produces -25291 (errSecNotAvailable)let query = [kSecValueRef: self, kSecReturnPersistentRef: true] // Produces -25300 (errSecItemNotFound)Is it possible to get a persistent keychain ref to a SecIdentityRef on iOS? (For that matter, I need to do the same on OS X, but I've generally found that the OS X APIs are more likely to do what I expect.)
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
0 Replies
639 Views
My app needs to upload some media files to a server. Usually it's only a few, but occasionally a user will have 1,000+ files to upload. These files are user data and we want to maximize the chances of the files making it to the server, so we're using a background URL session to queue up the uploads. However, what we're seeing is that for some users, the uploads just… stall. We're reconnecting to the background session, and the requests are all there; they're just not making any progress. This is true even when the app is in the foreground. I've configured the background URL session to use isDiscretionary = false, which I believe should indicate to the system that we really want these uploads to happen right away if possible. If we switch to using a regular session instead of a background URL session, the uploads all go through just fine. What we'd like is for the uploads to go through just like a normal session while the app is in the foreground. When the app is quit, we'd love for the uploads to continue in the background at whatever rate the system chooses. It seems to me that the system is throttling the uploads, even while the app is in the foreground. Is that something that happens with background URL sessions? Is there a way to make it not happen? Here's how I'm configuring the URL session: let config = URLSessionConfiguration.background(withIdentifier: "my-custom-identifier") config.isDiscretionary = false config.allowsCellularAccess = true config.sessionSendsLaunchEvents = false
Posted
by bjhomer.
Last updated
.
Post marked as solved
4 Replies
888 Views
I've got an iOS app and a Mac app. I'm trying to use ASAuthorizationPasswordProvider to implement the "existing user sign in" flow for Sign in with Apple. It's working correctly on both platforms. when there's an existing Sign in with Apple user. However, I'm having trouble getting macOS to show suggested credentials for passwords from the keychain. ASAuthorizationPasswordProvider claims to work on both platforms, and I'm using the same code on both, but it's not working on Mac. Here's the relevant code: let appleIDRequest = ASAuthorizationAppleIDProvider().createRequest() appleIDRequest.requestedScopes = [.email, .fullName] let passwordRequest = ASAuthorizationPasswordProvider().createRequest() let controller = ASAuthorizationController(authorizationRequests: [appleIDRequest, passwordRequest]) controller.delegate = self controller.presentationContextProvider = self controller.performRequests() I have verified that both Mac and iOS have the correct "Associated Domains" capability enabled. Is there something else I need to do to get this to work on Mac?
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
0 Replies
560 Views
I am trying to use composable collection view layouts to build an interface that has sections and then "sub-sections". Imagine a photo picker with a section for each month, and then a separate sub-section for each day within the month. The month header would be sticky, while the headers on each date section would not. I know iOS 14 has support for outline-style collection views which would probably work for representing sub-sections, but I'm hoping to do this in a way that's compatible with iOS 13. My thought was that I could do something like this: Section (Sticky boundary item of kind "month-header") Day Group (see below) Day Group (Non-sticky boundary item of kind "day-header") Custom layout that provides the layout for each day view You might think the day group could just be a wrapper for some NSCollectionViewLayout.horizontal and .vertical rows, but remember that all of the items for the entire month are in the same section. If the first day only has 7 photos, I need a way to tell the group to only provide layout for 7 items, and then the section should create another instance of the group to represent the next day. The only way I know to do that is to make a custom group layout that manually specifies the grid layout for the 7 items in that day. The problem that I'm having is that I see no way for the group layout to know which item it's starting at. Ideally, I'd like for the custom group layout provider to receive an itemIndex parameter. If it's 0, I'd know I'm looking at day 1. If it's 7, I'd be able to do the math to know that we've moved on to day 2, etc. Unfortunately, I see no way for the group to know that. I cannot assume that the group provider will be called only once sequentially for each group instance in the section; I already tried that and was quickly proven wrong. Is there a better way to do this? Notes on alternatives I've tried: I could instead just provide a series of custom groups, each tailored to have the correct number of items for that group, like so: Section (Sticky boundary item of kind "month-header") Day Group 1 Day Group 2 ... Day Group 31 Day Group 1 (Non-sticky boundary item of kind "day-header-1" to serve as day header) Custom layout for day 1 Day Group 2 (Non-sticky boundary item of kind "day-header-2" to serve as day header) Custom layout for day 2 Day Group ... Unfortunately, this means that the each day header would have to have a separate supplementary item kind, because you cannot reuse the same supplementary item kind for two different layout groups. This is workable, but results in a much more complex layout description, and means I have to register 32 supplementary item kinds. This all feels like a terrible hack.
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
6 Replies
832 Views
It seems like in the new forums, posts are organized by tags instead of by hierarchical categories. That's beneficial in some ways. However, I'm having a hard time figuring out how to find new posts. For example, I wanted to check whether anyone had asked this question previously. In the old forums, I might have gone to the "Developer Forums" category and looked at recent posts. I can't do that here, and it's not clear to me what I should do instead. I search for a "new forums" tag, but didn't find one. I searched for a topic with similar words, but didn't find one. Is there a way to browse existing content (tags, posts, etc.) other than the "Top Posts/Tags/Users" shown on the home screen? (Ironically… I can see the list of existing tags in the "Tags" box when creating a new post as I'm doing right now, but I haven't found any other way to see that list.)
Posted
by bjhomer.
Last updated
.
Post not yet marked as solved
0 Replies
1.3k Views
I want to add an image view to a UITextView. I have a few requirements:1. The image takes up the entire width of the editor. It basically acts as a paragraph break and fills all the space between paragraphs.2. It should not be possible to place the cursor on the row of the image; the cursor should ignore the image entirely.3. The image should retain its position in the text.I can think of a few approaches, but they all seem to fail one of my requirementsOption 1: Use NSTextAttachmentI can make a large text attachment that occupies the full width of the editor. This ensures that the attachment will always be placed on its own line, but does not prevent the cursor from being placed on that line. That ends up being a problem, because the cursor ends up the height of the image. This looks bad, and also causes all sorts of problems when UITextView tries to scroll the cursor to be visible but the cursor is taller than the visible area. The user never expects to type on the line containing the image; they would type either above or below it, so I'd like to disallow it being placed there at all.Option 2: Use NSTextContainer.exclusionPathsI can set up an exclusion path that causes text to flow right around my content. This makes the cursor behave as expected, but there's no way to make the exclusion paths flow with the text; when I add more text above the image, the text starts flowing underneath. I'd have to update the exclusion paths after every key press, and that seems like a recipe for terrible performance.Option 3: Multiple text containersI can add multiple text containers to the layout manager and put each text segment in its own text view. Then I can put the image between two adjacent text views and everything is happy. This works great on macOS, but on iOS, UITextView completely disables editability if you have multiple text views attached to a single layout manager. The content becomes read-only. Dead end.Option 4: Something with control characters, maybe?TextKit has various APIs around control characters. Is there some way to embed a control character in the text, and have the text view treat it somewhat like a newlne that has really large advancement? And then later, I could ask the layout manager where that character was and float an image view over the top of it? This seems like a promising option, but I'm not familiar enough with the APIs around control characters to be sure what's possible here.
Posted
by bjhomer.
Last updated
.