Post

Replies

Boosts

Views

Activity

Reply to Inform users that they need to delete and reinstall the app
As a user, being told to delete an app and reinstall a new version is a terrible experience. I am more than likely to just delete your app unless it's something I desperately need. But, can't you do this with Core Data migration? I've done it before. Create a new version of your model. Create a mapping model that maps from your old version to the new one. Tell Core Data how to manage the data changes. Let's say you have this in version 1: name: String joinDate: Date detailsId: String and you want to have a new Details entity and join them up, version 2 would be something like this: name: String joinDate: Date detailsId: String // You can leave this for now, and delete it in a later mapping model details: // Relationship to new Details entity, which is: // Details entity: id: String // Copy the detailsId from version 1 to here // Fill out the rest of the entity with default values, or migrations from the original entity Is that not possible?
Dec ’24
Reply to Trackpad becomes non-clickable
You're in the wrong place. These are the Developer Forums, where developers of apps for Apple's platforms ask each other for hints and tips on coding. Your question is more of a product support one, so I'd suggest you ask it over at the Apple Support Forums. However, because I'm a nice, friendly, helpful person, here's some help. It's not a fix, but it will let you control the pointer if your trackpad fails, so you can at least save what you're doing. Go to your System Settings, and search for "Mouse Keys". Enable it, and you can control the pointer. Here's an Apple Support document about it: https://support.apple.com/en-gb/guide/mac-help/mh27469/mac
Dec ’24
Reply to Iphone Pro Mac 16, 18.2 (22C152)
When you install a new version of iOS it takes a while for it to 'bed in'. It has to do various tasks in the background to get the device all updated properly. Some indexes are wiped and have to be recreated, for example. This takes battery power. This has been true for years. You said: I made sure all my apps where closed and at the end of day my only way to slow the leak was to put it in battery saving mode. Please don't do this. When you leave an app and go to the Home Screen, the app has about five seconds to finish what it needs to do, then it gets suspended. It uses zero power in the background. In fact, swiping those apps up out of the app switcher screen will cause you to use more power because the apps have to do more stuff when they start when you next launch them. It is a myth that apps use battery in the background. And finally, if your iPhone is on a beta version of iOS then yes, this is the right place to ask for help. However, you've only said that your other devices are on betas, so you're probably in the wrong place. Try the Apple Support Forums. Thanks.
Dec ’24
Reply to Refreshing widgets - policy and background tasks?
Right, so 72 entries is a sort-of limit. That should maybe be mentioned somewhere in the developer documentation to avoid anyone hitting issues. However, as this the Simulator and a development device those limits shouldn't apply. Anyway, thanks, but that still doesn't help. Even if I change the timeline to have just one day of 72 timeline entries (every 20 minutes for 24 hours), the widgets are still out of whack after just a few minutes. Due to the way timers work in SwiftUI, we developers are having to write a ton of fragile code to work around Apple's limited implementation. I want to show my users a countdown timer that has something like 12 days, 13:45:18. If I use the standard Text.init(date, style: .timer) I will get something like 301:45:18. The developer docs show this example: Example output: 2:32 36:59:01 Who in their right mind would ever want to see a countdown of 36 hours 59 minutes 1 second? No one. Users want to see "1 day 12 hours 59 minutes 1 second", or a friendlier "1 day, 12:59:01". And I can't just modulus the hours to remove 24 hour chunks because that doesn't cover different timezones and calendars. Even if I could, there's no way of intercepting the 36 hours bit of the timer output and changing it anyway. I have to write code that figures out how many hours, minutes and seconds should be displayed - which should never be more than 23:59:59 - to then be applied to the countdown timer, then display the larger units separately, i.e. "1 day". Apple's current implementation does not allow for this, so I'm having to write code that figures this out. And I've done it. And that code runs correctly. When I view the previews in Xcode I can see the correct timeline entries. Using Christmas at 9:00:00am as an example: A timeline entry is added with a date of Date.now, which for argument's sake is 11th December at 11:33:00pm. The event date - the actual date of the event, i.e. 9am on 25th December - is therefore 13 days, 9 hours and 27 minutes away. My widget should show 13 days 9:27:00, and it does. (Ignore the slight discrepancy between typing this and taking a screenshot, but you can see that the first entry in the timeline is 13 days 9:26:19.) Look at entry 3: the entry date is one minute later than 11:33:00pm, so it's showing a countdown timer of 13 days 9:25:19, i.e. one minute later. If I scroll through the preview entries I see each entry is 20 minutes closer to Christmas than before. This is correct. Now, when I deploy this to a device or even the Simulator, I see completely Whacko-Jacko timers. Here's a screenshot of a macOS Sequoia desktop widget (which is the same as that seen on my iPhone), showing 13 days 1:22:14 taken at 23:42:46: If you add 13 days 1:22:14 to 11th Dec 23:42:46 you get 25th Dec at 1:05:00am. How is that a valid countdown to 9:00:00am on Christmas Day?! Oh, and here's one that's apparently being refreshed every 20 minutes but has still managed to go over 23:59:59: As I said, I'm very close to just removing widgets altogether because they simply do not work as advertised, and your countdown timers are inflexible and unusable. I feel I also need to point out how you've managed to invent an extra second with your timers... When a normal timer is counting down to 0:00 and then counts into negative time, it goes: 0:03... 0:02... 0:01... 0:00... -0.01... -0.02... -0:03 Your timers go: 0:03... 0:02... 0:01... 0:00... 0:00... -0.01... -0.02... -0:03 How about I just send you a zip file of my entire application and you can figure out how to get it to work properly? I apologise if you feel this is an attack, but I have been dealing with this crud for years and I'm getting nowhere. There is likely a really simple fix, and if one of you wishes to spend some time writing a function that calculates the difference between two dates and puts those values into a user-friendly countdown timer, then please do so. I would be immensely grateful.
Topic: App & System Services SubTopic: General Tags:
Dec ’24
Reply to Refreshing widgets - policy and background tasks?
Xcode preview of the timeline entries with a timeline entry date of now (2024-12-10 23:07, the second date in the view) shows a widget with 14 days, 9:52:xx seconds counting down to the event date of 2024-12-25 09:00, the first date in the view). This is correct. From the entry date to the event date there are 14 days, 9 hours, 52 mins xx seconds to that time. All good. Now look at that widget on my macOS desktop (exactly the same as on the iPhone): 14 days, 8:30:xx. It's an hour and 20 minutes out. Why? The moment I relaunch the app on my iPhone it will update the widgets on the desktop and they'll show the correct countdown time. Xcode previews show the right times, then when the app is deployed to a device they just forget that timeline altogether and make it up. I obviously cannot ask the user to relaunch my app every couple of hours to make sure the widgets are correct. This should just work. Xcode's previews show that what I've done is correct - my timeline is correct - so why is it wrong on a device? It's so frustrating.
Topic: App & System Services SubTopic: General Tags:
Dec ’24
Reply to Refreshing widgets - policy and background tasks?
Okay, so background tasks don't work at all, and apparently aren't the way to go with refreshing widgets because the refresh policy .atEnd is meant to simply re-run the timeline func again to get new entries. In my experience, this never works; it is never called, and the widgets never display the right entries from the initial timeline anyway. Xcode's previews show the right entries, so why the widgets deviate so much from them is anyone's guess. I am 90% of the way to thinking of just removing widgets from my app as they simply do not work as advertised, and I could do without the migraines. If an Apple developer is actively reading this, how about you help a guy out? I've raised feedback reports and they're still "open" with no other linked reports. I cannot be the only person in the world who can't get widgets to work properly. I have been trying to get these things to work properly since they were introduced years ago. They don't work, and Apple won't help.
Topic: App & System Services SubTopic: General Tags:
Dec ’24
Reply to How to get user's email? Login with apple id
If an email from you to a Hide My Email address isn't being forwarded to the original email address, then that's an issue with Apple's Hide My Email service, and you should raise a bug here: https://feedbackassistant.apple.com/. How have you determined it's not being forwarded? Have you set up your own HME address, sent an email to it, and not received it at the original address?
Topic: Privacy & Security SubTopic: General Tags:
Dec ’24
Reply to Nested TimelineView and List cause hang issue
What happens if you remove the unnecessary second TimelineView? struct ContentView: View { var body: some View { TimelineView(.everyMinute) { _ in List { text } } } var text: some View { Text("Hello") } } You're already updating the contents of the first TimelineView every minute on the minute, so why do you need a second one inside? Maybe, if that doesn't work, how about putting the second one back and removing the first? struct ContentView: View { var body: some View { List { TimelineView(.everyMinute) { _ in text } } } var text: some View { Text("Hello") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Dec ’24
Reply to How to get user's email? Login with apple id
When someone uses Hide My Email, Apple generates a random email address - which is the email address you receive. That email address forwards emails to the user's original email address. You don't say why/how the email "doesn't work", but if you're getting errors like "the email address doesn't exist", that's likely because user's are able to delete those relay email addresses. The point of someone using "Hide My Email" is to hide their actual email address. There is no way you can get the user's actual email address - they didn't want to share it with you - and you should treat the email you have received as that user's email address. If that email address is bouncing emails, then: Is a user still trying to log into your website with that email address? If so, then you should let them log in (their account credentials are still valid, you're just getting bounced emails), then inform them that their email address isn't working. This is standard practice. If emails to that user are bouncing, then you ask for an updated email address. If a user isn't logging in with that email, then try and send them an email after about a year saying their account will be closed/deleted in 90 days if they don't sign back in and provide a valid email address. They may or may not get the email, but at least you have a record of telling them via the only email address you have for them, that their account will be closed.
Topic: Privacy & Security SubTopic: General Tags:
Dec ’24
Reply to format percentages
print(String(format: "%.0f%%", 33.3333)) prints 33% Explanation: String(format: "%.2f", value) %.2f formats and rounds to the number of decimal places given, in this case, 2. For zero decimal places you just use 0, i.e.: String(format: "%.0f", value) To display the percentage sign as a percentage sign, and not be interpreted by the formatting you need to add in two of them: String(format: "%.2f%%", value) So: String(format: "%.2f%%", 67.85762) is 67.86%. String(format:...) rounds accordingly, i.e.: let pi = 3.1415926535 String (format: "%.10f", pi) // "3.1415926535" String (format: "%.9f", pi) // "3.141592654" String (format: "%.8f", pi) // "3.14159265" String (format: "%.7f", pi) // "3.1415927" String (format: "%.6f", pi) // "3.141593" String (format: "%.5f", pi) // "3.14159" String (format: "%.4f", pi) // "3.1416" String (format: "%.3f", pi) // "3.142" String (format: "%.2f", pi) // "3.14" String (format: "%.1f", pi) // "3.1" String (format: "%.0f", pi) // "3"
Dec ’24
Reply to Inform users that they need to delete and reinstall the app
As a user, being told to delete an app and reinstall a new version is a terrible experience. I am more than likely to just delete your app unless it's something I desperately need. But, can't you do this with Core Data migration? I've done it before. Create a new version of your model. Create a mapping model that maps from your old version to the new one. Tell Core Data how to manage the data changes. Let's say you have this in version 1: name: String joinDate: Date detailsId: String and you want to have a new Details entity and join them up, version 2 would be something like this: name: String joinDate: Date detailsId: String // You can leave this for now, and delete it in a later mapping model details: // Relationship to new Details entity, which is: // Details entity: id: String // Copy the detailsId from version 1 to here // Fill out the rest of the entity with default values, or migrations from the original entity Is that not possible?
Replies
Boosts
Views
Activity
Dec ’24
Reply to Trackpad becomes non-clickable
You're in the wrong place. These are the Developer Forums, where developers of apps for Apple's platforms ask each other for hints and tips on coding. Your question is more of a product support one, so I'd suggest you ask it over at the Apple Support Forums. However, because I'm a nice, friendly, helpful person, here's some help. It's not a fix, but it will let you control the pointer if your trackpad fails, so you can at least save what you're doing. Go to your System Settings, and search for "Mouse Keys". Enable it, and you can control the pointer. Here's an Apple Support document about it: https://support.apple.com/en-gb/guide/mac-help/mh27469/mac
Replies
Boosts
Views
Activity
Dec ’24
Reply to Bug in ios 18.2
Sorry, where's the bug? You searched for ChatGPT, and the results are pointing you to it...?
Replies
Boosts
Views
Activity
Dec ’24
Reply to Iphone Pro Mac 16, 18.2 (22C152)
When you install a new version of iOS it takes a while for it to 'bed in'. It has to do various tasks in the background to get the device all updated properly. Some indexes are wiped and have to be recreated, for example. This takes battery power. This has been true for years. You said: I made sure all my apps where closed and at the end of day my only way to slow the leak was to put it in battery saving mode. Please don't do this. When you leave an app and go to the Home Screen, the app has about five seconds to finish what it needs to do, then it gets suspended. It uses zero power in the background. In fact, swiping those apps up out of the app switcher screen will cause you to use more power because the apps have to do more stuff when they start when you next launch them. It is a myth that apps use battery in the background. And finally, if your iPhone is on a beta version of iOS then yes, this is the right place to ask for help. However, you've only said that your other devices are on betas, so you're probably in the wrong place. Try the Apple Support Forums. Thanks.
Replies
Boosts
Views
Activity
Dec ’24
Reply to OTP code being used against me
Just wipe your phone and see if you can get back into the various apps and accounts. Have you tried using a Mac or Windows PC to access your bank accounts instead? But anyway, this isn't the place for your issue.
Topic: Community SubTopic: Apple Developers Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to iOS 17.7.2 bug
Have you raised a Feedback report? If not, please do so at https://feedbackassistant.apple.com/ then post the FB number here.
Topic: Community SubTopic: Apple Developers Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to Refreshing widgets - policy and background tasks?
Right, so 72 entries is a sort-of limit. That should maybe be mentioned somewhere in the developer documentation to avoid anyone hitting issues. However, as this the Simulator and a development device those limits shouldn't apply. Anyway, thanks, but that still doesn't help. Even if I change the timeline to have just one day of 72 timeline entries (every 20 minutes for 24 hours), the widgets are still out of whack after just a few minutes. Due to the way timers work in SwiftUI, we developers are having to write a ton of fragile code to work around Apple's limited implementation. I want to show my users a countdown timer that has something like 12 days, 13:45:18. If I use the standard Text.init(date, style: .timer) I will get something like 301:45:18. The developer docs show this example: Example output: 2:32 36:59:01 Who in their right mind would ever want to see a countdown of 36 hours 59 minutes 1 second? No one. Users want to see "1 day 12 hours 59 minutes 1 second", or a friendlier "1 day, 12:59:01". And I can't just modulus the hours to remove 24 hour chunks because that doesn't cover different timezones and calendars. Even if I could, there's no way of intercepting the 36 hours bit of the timer output and changing it anyway. I have to write code that figures out how many hours, minutes and seconds should be displayed - which should never be more than 23:59:59 - to then be applied to the countdown timer, then display the larger units separately, i.e. "1 day". Apple's current implementation does not allow for this, so I'm having to write code that figures this out. And I've done it. And that code runs correctly. When I view the previews in Xcode I can see the correct timeline entries. Using Christmas at 9:00:00am as an example: A timeline entry is added with a date of Date.now, which for argument's sake is 11th December at 11:33:00pm. The event date - the actual date of the event, i.e. 9am on 25th December - is therefore 13 days, 9 hours and 27 minutes away. My widget should show 13 days 9:27:00, and it does. (Ignore the slight discrepancy between typing this and taking a screenshot, but you can see that the first entry in the timeline is 13 days 9:26:19.) Look at entry 3: the entry date is one minute later than 11:33:00pm, so it's showing a countdown timer of 13 days 9:25:19, i.e. one minute later. If I scroll through the preview entries I see each entry is 20 minutes closer to Christmas than before. This is correct. Now, when I deploy this to a device or even the Simulator, I see completely Whacko-Jacko timers. Here's a screenshot of a macOS Sequoia desktop widget (which is the same as that seen on my iPhone), showing 13 days 1:22:14 taken at 23:42:46: If you add 13 days 1:22:14 to 11th Dec 23:42:46 you get 25th Dec at 1:05:00am. How is that a valid countdown to 9:00:00am on Christmas Day?! Oh, and here's one that's apparently being refreshed every 20 minutes but has still managed to go over 23:59:59: As I said, I'm very close to just removing widgets altogether because they simply do not work as advertised, and your countdown timers are inflexible and unusable. I feel I also need to point out how you've managed to invent an extra second with your timers... When a normal timer is counting down to 0:00 and then counts into negative time, it goes: 0:03... 0:02... 0:01... 0:00... -0.01... -0.02... -0:03 Your timers go: 0:03... 0:02... 0:01... 0:00... 0:00... -0.01... -0.02... -0:03 How about I just send you a zip file of my entire application and you can figure out how to get it to work properly? I apologise if you feel this is an attack, but I have been dealing with this crud for years and I'm getting nowhere. There is likely a really simple fix, and if one of you wishes to spend some time writing a function that calculates the difference between two dates and puts those values into a user-friendly countdown timer, then please do so. I would be immensely grateful.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to Refreshing widgets - policy and background tasks?
Xcode preview of the timeline entries with a timeline entry date of now (2024-12-10 23:07, the second date in the view) shows a widget with 14 days, 9:52:xx seconds counting down to the event date of 2024-12-25 09:00, the first date in the view). This is correct. From the entry date to the event date there are 14 days, 9 hours, 52 mins xx seconds to that time. All good. Now look at that widget on my macOS desktop (exactly the same as on the iPhone): 14 days, 8:30:xx. It's an hour and 20 minutes out. Why? The moment I relaunch the app on my iPhone it will update the widgets on the desktop and they'll show the correct countdown time. Xcode previews show the right times, then when the app is deployed to a device they just forget that timeline altogether and make it up. I obviously cannot ask the user to relaunch my app every couple of hours to make sure the widgets are correct. This should just work. Xcode's previews show that what I've done is correct - my timeline is correct - so why is it wrong on a device? It's so frustrating.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to Refreshing widgets - policy and background tasks?
Okay, so background tasks don't work at all, and apparently aren't the way to go with refreshing widgets because the refresh policy .atEnd is meant to simply re-run the timeline func again to get new entries. In my experience, this never works; it is never called, and the widgets never display the right entries from the initial timeline anyway. Xcode's previews show the right entries, so why the widgets deviate so much from them is anyone's guess. I am 90% of the way to thinking of just removing widgets from my app as they simply do not work as advertised, and I could do without the migraines. If an Apple developer is actively reading this, how about you help a guy out? I've raised feedback reports and they're still "open" with no other linked reports. I cannot be the only person in the world who can't get widgets to work properly. I have been trying to get these things to work properly since they were introduced years ago. They don't work, and Apple won't help.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to How to get user's email? Login with apple id
If an email from you to a Hide My Email address isn't being forwarded to the original email address, then that's an issue with Apple's Hide My Email service, and you should raise a bug here: https://feedbackassistant.apple.com/. How have you determined it's not being forwarded? Have you set up your own HME address, sent an email to it, and not received it at the original address?
Topic: Privacy & Security SubTopic: General Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to Female English Indian Siri Voice Pronounces Certain Words in the American Pronunciation Instead of the correct Pronunciation
You should probably raise this as a bug in the usual way. It won't really get progressed if it's only posted in these Developer Forums. You need to raise each issue you find separately at https://feedbackassistant.apple.com/ You can post the FB numbers here if you want, so that others can link to them.
Replies
Boosts
Views
Activity
Dec ’24
Reply to Nested TimelineView and List cause hang issue
What happens if you remove the unnecessary second TimelineView? struct ContentView: View { var body: some View { TimelineView(.everyMinute) { _ in List { text } } } var text: some View { Text("Hello") } } You're already updating the contents of the first TimelineView every minute on the minute, so why do you need a second one inside? Maybe, if that doesn't work, how about putting the second one back and removing the first? struct ContentView: View { var body: some View { List { TimelineView(.everyMinute) { _ in text } } } var text: some View { Text("Hello") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to iOS Widget is not displaying timer in iOS 18
Maybe you could provide some code and we'll take a look?
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to How to get user's email? Login with apple id
When someone uses Hide My Email, Apple generates a random email address - which is the email address you receive. That email address forwards emails to the user's original email address. You don't say why/how the email "doesn't work", but if you're getting errors like "the email address doesn't exist", that's likely because user's are able to delete those relay email addresses. The point of someone using "Hide My Email" is to hide their actual email address. There is no way you can get the user's actual email address - they didn't want to share it with you - and you should treat the email you have received as that user's email address. If that email address is bouncing emails, then: Is a user still trying to log into your website with that email address? If so, then you should let them log in (their account credentials are still valid, you're just getting bounced emails), then inform them that their email address isn't working. This is standard practice. If emails to that user are bouncing, then you ask for an updated email address. If a user isn't logging in with that email, then try and send them an email after about a year saying their account will be closed/deleted in 90 days if they don't sign back in and provide a valid email address. They may or may not get the email, but at least you have a record of telling them via the only email address you have for them, that their account will be closed.
Topic: Privacy & Security SubTopic: General Tags:
Replies
Boosts
Views
Activity
Dec ’24
Reply to format percentages
print(String(format: "%.0f%%", 33.3333)) prints 33% Explanation: String(format: "%.2f", value) %.2f formats and rounds to the number of decimal places given, in this case, 2. For zero decimal places you just use 0, i.e.: String(format: "%.0f", value) To display the percentage sign as a percentage sign, and not be interpreted by the formatting you need to add in two of them: String(format: "%.2f%%", value) So: String(format: "%.2f%%", 67.85762) is 67.86%. String(format:...) rounds accordingly, i.e.: let pi = 3.1415926535 String (format: "%.10f", pi) // "3.1415926535" String (format: "%.9f", pi) // "3.141592654" String (format: "%.8f", pi) // "3.14159265" String (format: "%.7f", pi) // "3.1415927" String (format: "%.6f", pi) // "3.141593" String (format: "%.5f", pi) // "3.14159" String (format: "%.4f", pi) // "3.1416" String (format: "%.3f", pi) // "3.142" String (format: "%.2f", pi) // "3.14" String (format: "%.1f", pi) // "3.1" String (format: "%.0f", pi) // "3"
Replies
Boosts
Views
Activity
Dec ’24