Post

Replies

Boosts

Views

Activity

Swift Compiler Issue?
I've encountered a strange issue with Swift and I wonder if this is a compiler error or if I didn't understand something correctly. The following sample code shows a weird issue (please ignore that the demo code itself would not make that much sense in this form, it's just the version from a big and more complicated project, where this would make more sense): class Test { var data: [String:[String:String]] = [:] func test() { let setValue: ((String, String, String) -> Void) = { [weak self] key, id, value in if self!.data[key] == nil { self!.data[key] = [:] } let oldValue = self!.data[key]![id] if oldValue == nil { self!.data[key]![id] = value } } setValue("0", "1", "2") } } When changing the "data" dictionary through the closure within the "test()" function, everything works as expected until the "if" condition where the oldValue is checked against nil. If I set a break point to this condition, the Xcode debugger tells me that oldValue is nil (which is expected), but the code within the if condition is NOT executed. The comparison oldValue == nil should be be true (because oldValue is actually nil), but the compiler seems to assume something else. But If I do not user "self!" but instead "self?" then it does work as expected and the code within the if condition is executed. What I am missing here? Is this the correct behavior or a compiler bug?
2
0
99
4d
Rejection of IAP with confusing reasoning
In one of My Apps I want have a "tip" option for users, so they can support the developer if they like the App. As a small tank you, "tipping" will unlock a small bonus feature (nothing essential, but nevertheless nice to have). According to the Guidelines this is perfectly fine and explicitly allowed. So a created a few IAP options with different prices as non-consumable one-time purchases and the same number of consumable one-time-purchases with the same prices (so no subscriptions at all). The idea is: users should be able to tip multiple times if they want to (actually many users of the old App version have asked for this) Non-consumable IAP items can only be purchased once, but these can be restored (for example when switching to a new device). Consumable IAP items can not be restored, but these can be purchased multiple times. The idea is to combine both, so it is possible to tip multiple times (via consumable IAPs) and to allow the restore of previous purchases (to unlock the bonus feature). To do this, the App would at first only offer the non-consumable IAP items in its "tipping" screen. Only after these were purchased, the App would then only offer the consumable IAP items. Users tipping only once would always purchase the non-consumable item that can be restored. Users who have tipped multiple times would also have purchased the non-consumable IAP once and in addition the consumable item, so they all can restore and unlock the bonus feature. And no one is confused about any internal differences (consumable vs non-consumable), because the users will always see only one tipping option. I've created these IAP items and send them to Apple for review together with this explanation. All the non-consumable items got approved, all the consumable items got rejected with the following bizarre and unhelpful note from the review board: 3.1.1 - new IAP type New type: Consumable Previous type: Non-Consumable Recommend: Download The binary of the app is new (more than 14 days). What exactly does this mean? I've read section 3.1.1 of the guidelines and nothing indicates anything which would allow any rejection here. And what does "the binary of the app is new" mean? Sure the App is new (currently the new version is tested via TestFlight), but what does this have to do with the IAP? With normal "Appstore rejections" there was always a link provided which allowed to contact the review team. But there's absolutely nothing available here. Just this bizarre note which doesn't give any clue what's wrong. Does anyone have an idea what's wrong, or what I need to do to get this approved? How can I contact the review team that is responsible for this IAP review? BTW: I've tried to get this approved again after changing the description/names of the localization a bit (because these are the only things which are marked in red), but the same strange note came back. And the localization title and description can not have a long text, so there're not that many possible variations available which describe the IAP correctly.
1
0
144
2w
WKWebView: Fullscreen API very unreliable on iPadOS 18.x
Since iPadOS 18.x WKWebView seems to have a bug within its Fullscreen API (which can be enabled via WKPreferences.isElementFullscreenEnabled). This bug has the effect that websites trying to make an element (for example a video player) fullscreen fail to do so. This does not always happen, most of the time the fullscreen mode does work fine, but sometimes (far too often to be ignored) it does not. If an instance of WKWebView shows this issue, it can not be "fixed" by reloading the page or loading other pages, this issue exists in this instance forever. My App is a web browser App so I can create and remove WKWebView instance easily (by opening or closing Tabs). And there are times where I never see this bug, and times where ever other tab shows this bug. It's totally unreliable. The App does not show any issues at all when running under iPadOS 17 or older. The issue is only present under iPadOS 18.x. After some testing I've found out that when the bug has affected an instance of WKWebView, the JavaScript call element.requestFullscreen() will work if the element is a video element, but does no longer work if it is another element (like a DIV). If an instance of WKWebView is not affected by this bug, element.requestFullscreen() will work for all HTML elements. Does anyone has experienced this bug as well? And maybe found a workaround? Or maybe found a pattern which helps to find out what exactly is triggering this bug?
1
0
346
Oct ’24
WKWebView "showLockdownModeFirstUseMessage" delegate
How exactly am I supposed to implement the following delegate method of WKWebView? func webView(_ webView: WKWebView, showLockdownModeFirstUseMessage message: String, completionHandler: @escaping (WKDialogResult) -> Void) The problem: the delegate method is defined to be available since iOS 13. But "WKDialogResult" in the completion handler is declared to be available since iOS 16. So this is already very odd and probably a bug in the API declaration. When I make the delegate method available since iOS 16 (via @available (iOS 16.0,*)) then Xcode gives me an error stating that this method must be provides for iOS 14 and later. But when it is made available since iOS 14 (or 13), then I get the error that WKDialogResult is only available since iOS 16. So this looks like a big messy bug in the API declaration, or did I miss something here? It would not the first bug in the API declaration of the WKWebView where the availability is wrong (for example the property "upgradeKnownHostsToHTTPS" is declared to available since iOS 14.5, but in reality it is only available since iOS 16 and would crash when used under iOS 14.5)
0
0
396
Mar ’24
StoreKit 2 - AppTransaction.originalAppVersion confusion
I've watched some of the WWDC session videos about this topic and read the documentation and header files, but it is still confusing... Because I change the pricing model of my iOS App (it was a paid App and now it will be a free App with an In-App purchase), I want to check if a user of my App purchased the App in the past. So user who have already paid in the past will get the full access without the need to pay the IAP, while new users would have to do this. In one of the WWDC videos exactly this topic was covered and the solution would be to check out AppTransaction.originalAppVersion. This would be a simple and easy solution... ...Unless I read the information from the header file and documentation for this API. Here it says: The string value contains the original value of the CFBundleShortVersionString for apps running in macOS, and the original value of the CFBundleVersion for apps running on all other platforms. The problem here is that when I check the Info.plist of iOS Apps, the CFBundleShortVersionString is used for the main App version and CFBundleVersion is used for the "build" number. According to the cited documentation from above, AppTransaction.originalAppVersion would be totally uselesss on the iOS platform, because it would only return the build number and not the version number. So I'm confused. Can I use AppTransaction.originalAppVersion to get the original version that was purchased for iOS Apps? If yes, the documentation must be wrong and misleading. If no, how can I do this? I'm currently in testing and I only get "1.0" as originalAppVersion within the beta release. This could be either because I really only get the useless build number, or I get the "real" version because the App is on the device since version "1.0" on my device, or it is just a limitation of XCode while testing that it is returning version "1.0" but would return the correct version when the App was installed from the AppStore.... Can someone bring some light into this topic? Am I missing something or did I understand something wrong?
2
4
1k
Nov ’23
flooded with awdd-consolidated logs
On my iPhone 14 Pro I can observe that each day several (2-6) new logs appear in the "analytics" section of the system settings (I do have several hundreds already). Normally logs will be moved to the Mac when syncing the device to the Mac. But these "awdd" logs do not sync. I just get more and more on the device. It looks like this is going on from the start (when I purchased the device). Is something wrong with the device? How can I fix this, and how can I get rid of all these logs? It's almost impossible to find crash logs and other logs I'm interested in among all these awdd logs. The iPhone was always running the latest iOS releases. At the same time, my iPad did not create these logs multiple times a day (it also has a few, but only approx 2 per month).
0
0
843
Mar ’23
Advanced Data Protection for files via iCloud sync (UbiquityContainer)
The iCloud has the iCloud Drive (a could storage where the user can store any files and which Apps can access and share) and files in an "UbiquityContainer", which will be synced and only accessible to the App itself, not visible/accessible to other Apps. The information about the new Advanced Data Protection (ADP) only mentions iCloud Drive to be covered by ADP. Are the synced files within the UbiquityContainer also protected by ADP? If not, how can these be included?
0
0
764
Jan ’23
Watch Complications (WidgetKit) do not show anything on device
I’m trying to create complications für the Watch using the new WidgetKit. While the complications do show up fine in the preview in Xcode and also in the Simulator, on a real device the complications do never shown anything. The complications are listed and can be selected in the watch face settings, but the preview is always black, and when added to a watch face, it shows nothing. I can tap on this „nothing“ and the App launches, so the complication is actually there. But it doesn’t show anything. This is also true for the Watch App on the iPhone, which lets me add the complications to a watch face, but it also shows nothing. But in the Simulator everything works as expected, the complications show their content just fine. So it looks like the code is fine. The iPhone runs the iOS 16.1, and the watch runs watchOS 9.1 (right now the latest public releases) Does anyone having the same issue and maybe a solution or a hint, what exactly I should check?
4
3
2.5k
Nov ’22
Accessibility Labels within the Dynamic Island
I'm trying to make my Live Activity (dynamic Island, lock screen) accessible for blind users as well. This does work, but not as I would expect it. The problem is that VoiceOver reads all the texts multiple times (at least 2 times, sometimes even 3 or 4 times) Even this simple example...       ActivityConfiguration(for: LiveAttributes.self) { context in Text("aaa")         } dynamicIsland: { context in             DynamicIsland {                 DynamicIslandExpandedRegion(.leading) { Text("bbb")                 }                 DynamicIslandExpandedRegion(.trailing) { Text("ccc")                 }                 DynamicIslandExpandedRegion(.center) { Text("ddd")                 }             } compactLeading: {                 Text("www")             } compactTrailing: {                 Text("yyy")             } minimal: {                 Text("zzz")             } will read "www www yyy yyy" just by tapping the dynamic island (not expanded) when VoiceOver is enabled. I would expect that all text would be read only once ("www yyy"). Is this a bug? Can I prevent that the text is read multiple times? Anyone having similar problems and maybe a solution?
1
0
872
Nov ’22
Local backup of device always requires to enter the device code since iOS 16.1 (Beta and RC)
Is this a bug or and intentional behavior of iOS 16.1: whenever I connect the device to my Mac and the Mac starts to create local backup of the device, I now have to enter the code of my iPhone on my device to confirm that I trust this computer? In the past this was only necessary once and after I confirmed that I trust the computer, the Mac would silently create a backup whenever the device was connected. Now this is no longer possible. Every single time a backup should be created (even when clicking on the "create backup now" button directly after a backup has just finished - so the device was not disconnected and connected again - I have to enter the code again). And the issue only affects the backup, all other data (music, podcasts, photos, contacts etc) do sync fine without entering the code (the bad thing is that I have to manually skip the backup otherwise the Finder would simply wait forever for the code to be entered on the device). Also Xcode accepts the device and installs/debugs Apps without any issues. This means it is not impossible to simply connect the device to the computer to let it sync. I always have to confirm that I trust the computer otherwise the whole syncing process stops just because of the backup... So what is wrong with the local backup feature? Is this broken now in iOS 16.1? Or is this intentional? BTW: This happens on 2 iPhones (both run iOS 14.1 RC), so it doesn't seem anything "damaged" on the device...
1
0
1k
Oct ’22
How to read property list (binary format) if the iOS fails to load it via NSPropertyListSerialization
In my App I work with a "tree" structure (nested NSArrays and NSDictionaries) and have stored them in the file system using NSPropertyListSerialization, which always works fine. In general loading the same structure via NSPropertyListSerialization works fine too, but if the "tree" is getting larger (nested deeper), NSPropertyListSerialization can no longer read the file (even if it was able to saved it without error before). It will fail with the error "Too many nested arrays or dictionaries". The issue seems to be the nesting level, not the general amount of nodes in the property list, because the file itself is very small (about 50 KB) . I've never seen this in the past, so this might be a new issue of iOS 14. So my question is: is there another way to read the propertylist file? The problem is that the file is stored in the binary format (not the plain XML format), so just using a general XML parser is not an option, the binary file format seems to be undocumented by Apple.
10
0
4.1k
Mar ’21
Notarization or Gatekeeper issues when downloading archive with certain Apps
I have a strange issue with Notarization or Gatekeeper under macOS 10.15.6. After signing and exporting my App from the Xcode Organizer, I'm using atool to notarize my App (*). This works fine and when everything is finished, I also check with… spctl -a -vv App I get the status… App: accepted source=Notarized Developer ID origin=Developer ID Application: xxxx So everything is fine. I create a ZIP archive with the App and some read.me files and put it on my web page so users can download the App. So now the weird which I don't understand: If I download the ZIP archive with Safari, extract the archive, I can launch the App and get a notification from gatekeeper that the App was downloaded from the internet, it was checked for malware, none were found and I can launch the App and cancel. The App works fine from now on (why do I get this warning in the first place? Shouldn't the Notarization and signing of the App prevent these kinds of warnings?) For the App from the ZIP spclt reports: App: accepted source=Notarized Developer ID origin=Developer ID Application: xxxx If I download the archive with the old version of my App using its "search for Update" feature (the App was originally developed and notarised under macOS 10.14, written in Objective C), and extract the ZIP archive and launch the App, it launches without any Gatekeeper warning (which is what I would have expected). For the App from the ZIP spclt reports: App: accepted source=Notarized Developer ID origin=Developer ID Application: xxxx If I launch the App with the new(!) version of my App (a complete rewrite in Swift, so this is a new Code project, but with the same bundle ID as the old App), extract the Archive and try to launch the downloaded App, the finder gives me an Error message "The App 'App' can not be opened" (no further description). Launching the App fails!!! For the App from the ZIP spclt reports: App.app: File created by an AppSandbox, exec/open not allowed So somehow the Finder seems to treat the ZIP file different, depending of the App which has downloaded the file. This makes no real sense to me. The App is signed and notarized correctly, shouldn't this be enough to let the Finder check that the App is not modified and can be launched without error or warning? So my question is, why does it behave in three different ways with exactly the same ZIP archive, depending of the App which has downloaded the ZIP archive. And the most important question is: What do I need to do so that my new version of may App can download the ZIP archive (for the search for Updates" feature) so that when extracting the ZIP the App can be opened successfully without error? Notes: (*) Xcode is unable to notarize my App. It always fails with the error, that I had to accept certain contracts first. This seems to be an old of Xcode. This issue seems to occur when a developer is a member of other developer teams. Xcode seems to check the wrong contracts (from the other teams), not your own. Fortunately "atool" works.
4
0
1.9k
Sep ’20
How to save a photo in the album?
In order to save a photo in the album you can use different APIs: ) You can use the simple UIImageWriteToSavedPhotosAlbum() call, which takes an UIImage object as parameter. The problem here is that because the image must be an UIImage, you can no longer save the original(!) photo data. The file format, animations for GIFs and all metadata will be lost. ) You can use the "PHPhotoLibrary" framework, which can save the original photo data, including animations, metadata etc. So this would be the best option. The big problem is with the access privileges: I do only want to save photos in the album, not read them. So theoretically I would only need the key "NSPhotoLibraryAddUsageDescription" in the Info.plist. But this only works for the first approach (UIImageWriteToSavedPhotosAlbum). The seconds approach does not work with "NSPhotoLibraryAddUsageDescription", it will just crash and the Xcode console states that the key "NSPhotoLibraryUsageDescription" is required, so this requests not only write access but also read access. For getting a new iOS 14 entitlement for my App, I am no longer allowed to have the "NSPhotoLibraryUsageDescription" key in the Info.plist, which makes it impossible to save the original photo data in the album (because PHPhotoLibrary requires the key NSPhotoLibraryUsageDescription). Is the another way to save the original image data in the album? Like an animated GIF, or photos with meta data? Note, I can only have the key "NSPhotoLibraryAddUsageDescription" in the Info.plist?
1
0
2.5k
Aug ’20
AVSpeechSynthesizer crashes with German voice only
In one of my Apps I'm using AVSpeechSynthesizer let the watch speak text to the user, which works great in general, but not when selecting a German voice (the only one that is available under watchOS 6,1,1 is "Anna-compact"). With the German voice to sperak German text, that App always crashes under watchOS 6.1.1 (it did not crash under watchOS 5, and I think not under early watchOS 6 releases, though I can't really tell when this issue started).The code which starts the speech output is simple: AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:text]; utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"de"]; [self.speechSynthesizer speakUtterance:utterance];The crash happens within the speakUtterance call, the App never returns from this call, also none of the delegeta methods of AVSpeechSynthesizer is ever called here, so the crash occurs while the watchOS initializes its internal data structures.The watchOS throws this exception:EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=80 MB, unused=0x0)and is crashing here (deep within the TTS component of watchOS):#00x1c4f370c in __CFToUTF8 ()#10x1c586f48 in __CFStringEncodeByteStream ()#20x1ceee8a4 in -[NSString(NSStringOtherEncodings) getBytes:maxLength:usedLength:encoding:options:range:remainingRange:] ()#30x1cffdecc in _NS_os_log_callback ()#40x1c1e538c in _os_log_fmt_flatten_NSCF ()#50x1c1e4c10 in _os_log_fmt_flatten_object ()#60x1c1f1308 in _os_log_impl_flatten_and_send ()#70x1c1f0bec in _os_log ()#80x1c1f6b90 in _os_log_debug_impl ()#90x3fbb466c in -[TTSRegexHelper _addRules:] ()#100x1bf945a8 in _dispatch_client_callout ()#110x1bfa0eb8 in _dispatch_lane_barrier_sync_invoke_and_complete ()#120x3fbb4368 in -[TTSRegexHelper addRules:] ()#130x04ecb050 in ___lldb_unnamed_symbol8$$TTSSpeechBundle ()#140x3fbc79ac in -[TTSVocalizer loadResource:mimeType:resourceURL:supportsAccurateWordCallbacks:] ()#150x3fbc4d4c in -[TTSSpeechServerInstance _loadVoiceResource:voiceResource:] ()#160x3fbc4960 in -[TTSSpeechServerInstance _initializeSpeechEngine:] ()#170x3fbc4b7c in -[TTSSpeechServerInstance _initializeSpeech:] ()#180x3fbc260c in -[TTSSpeechServerInstance _processCurrentRequest:] ()#190x3fbc3704 in -[TTSSpeechServerInstance _handleSpeechThread] ()#200x3fbc25c0 in _SpeechThread ()#210x1c1cc930 in _pthread_start ()I've no idea if this is a general issue/bug of watchOS 6.1.1 (it comes with damaged/broken voice files for German), or if only something on my watch got damaged for some unknown reason.Has anyone any experience in using AVSpeechSynthesizer on the AppleWatch and can reproduce this crash when using the German voice? Does it work under watchOS 6.1.1 on other devices?The text itself which should be read can not be the problem, because it crashes even with the text "1 2 3" (counting to 3), so no special characters (umlaut) or other fancy things involved. As test case "1 2 3" works great because this same text can be used for all languages and voices in the same way.
0
0
1.3k
Jan ’20
Transition from UIWebView to WKWebView
UIWebView is deprecated and Apple urges us to switch to WKWebView. Unfortuately WKWebView seems to be still lacking far too many features to be a valid replacement of UIWebView. Therefore I would likt to know if there are ideas how to achieve the following tasks...Proxy SupportWhen using UIWebView we could easily route all network through an App-specific proxy. All you need to do is to implement NSURLProtocol for "https" and "https" requests and handle the proxy there. WKWebView does not support NSURLProtocol and does not have any seting for a proxy. Configuring the proxy at system level is not an option, because there's only a proxy setting for WLAN available here, not for mobile internet (G3/G4/LTE), and the systems setting is applied to all other Apps as well. So all Apps which require their own Proxy can not use WKWebView right now (for example kid-safe browsers which need to filter the web). Caching, Offline UsageWhen using UIWebView and NSURLProtocol it's possible to control all network requests for the main web site and all its resources (images, JS, CSS etc). This is great for implementing a special caching for a real offline mode, so the App remains usable even if there's no internet connection. WKWebView doesn't support this. Cookie PolicyWKWebView doesn't allow to configure the cookie accept policy.
1
0
1.6k
May ’19