Post

Replies

Boosts

Views

Activity

Reply to Watch-Phone communication when Phone app is in background
Did you try sendMessage(_:replyHandler:errorHandler:)? Calling this method from your watchOS app while it is active and running wakes up the corresponding iOS app in the background and makes it reachable, which I believe is what you are looking for. Consider a simple phone speedometer app. I use CoreLocation to get GPS data and show the speed on the phone screen. It doesn't need to do anything in the background. Now I want to add watch support, sending the speed data from the phone to the watch using the applicationCOntext. (Let's ignore the possibility that the watch app could do this using its own GPS.) Now we need the phone app to run in the background, so that the watch can continue to show the speed when the phone is sleeping. So I enable the location background mode for the phone app and turn on CLLocationManager.allowsBackgroundLocationUpdates. This works but isn't ideal, because for users who don't have a watch etc. we are wasting power on the phone. So we really want to turn allowsBackgroundLocationUpdates on only when the watch app is in use. You suggest that I could use sendMessage(...) to have the watch tell the phone that it is in use. So, on the phone I would implement didReceiveMessage and change allowsBackgroundLocationUpdates. But... is it allowed for an app that has "when in use" location permission to turn on background location updates when it is already in the background? I guess it probably is, but I'll need to check. So when exactly do I want the watch to send its "I'm in use, send data" and "I'm no longer in use, stop sending data" messages? I guess I send them from appropriate WKApplicationDelegate methods. But I don't think I want the phone to turn its location updates on and off every time the user raises or lowers their arm. I guess I can send the messages that frequently, and have the phone app decide whether or not to turn updates off, perhaps with a timeout. Ziqiao, any thoughts about this? Thanks.
Topic: App & System Services SubTopic: Core OS Tags:
Feb ’25
Reply to When is the unverified branch of AppTransaction.shared entered?
if the unverified branch is entered + receipt validation fails, I'll feel OK about marking requests from that app as fraudulent. No, I think that if you get an unverified AppTransaction then you will also fail to verify the receipt on your server. Doing both is probably redundant. Be very cautious about blocking users based on any of this stuff. Assume that they can still write app store reviews when you block them.
Topic: App & System Services SubTopic: StoreKit Tags:
Feb ’25
Reply to SwiftUI and UIImage memory leak
Don’t store UIImages in your model, store the identifiers that you get from the photo picker (i.e. item.itemIdentifier). Then convert to images lazily. Except….. This doesn’t work if the user has granted “limited access” photo library permission. You’ll get identifiers, but you won’t be able to convert them to actual images. (That’s based on the UIKit version of the photo picker, but I guess it is the same here.) So…. if you care about that, you do need to get the image data immediately. There is a note in the docs about it supplying PNG data. I don’t understand the details of that; if that applies here you’ll want to do whatever’s necessary to get JPEG or HEIC or something. Then you need to ask yourself, if it’s unreasonable to have all the uncompressed images in RAM at the same time, is it reasonable or not to have all the compressed images in RAM? If that’s unreasonable, put them in the filesystem. One other thing - you don’t seem to be using thumbnails for your labels, but rather using the full-size UIImage.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’25
Reply to Animate colours in a SwiftUI Canvas
I found this web page: https://swiftui-lab.com/swiftui-animations-part3/ Specifically, the end section where it talks about Animatable Views. Quote: If we want the body of the view to be recomputed for every frame of the animation, then we adopt the Animatable protocol, by adding Animatable, and the animatableData property. So I've replaced the CustomCanvas above with this: struct CustomCanvas: View, Animatable { var fg_colour: Color.Resolved; var animatableData: Color.Resolved { get { fg_colour } get { fg_colour = newValue } }; var body: some View { Canvas { context, size in context.draw(image: Image(name: "foo"), toFitRect: some_rectangle); context.draw(text: Text("foo"), toFitRect: another_rectangle); } .foregroundStyle(fg_colour) } }; and now I pass fg_colour from the MainView: struct MainView: View { @Environment(\.self) var environment; var body: some View { PhaseAnimator([false,true], trigger: foo) { flash in ZStack { Capsule() .foregroundStyle(flash ? .red : .green) CustomCanvas(fg_colour: (flash ? .black : .white) .resolved(in: environment) } } animation: { flash in return .linear(duration: 0.5); } }; (Note Color isn't animatable, but Color.Resolved is; I need some extra stuff to make that work.) But this still doesn't work. The Canvas closure is still only called twice per update, not continuously to update with intermediate colours. Advice would be much appreciated.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’25
Reply to Animate colours in a SwiftUI Canvas
It seems that if I put the Canvas in a custom view, then it is called with flash==false and flash==true, but the colour doesn't transition smoothly from one to the other: (pseduo-code) struct CustomCanvas: View { var body: some View { Canvas { context, size in context.draw(image: Image(name: "foo"), toFitRect: some_rectangle); context.draw(text: Text("foo"), toFitRect: another_rectangle); } } }; struct MainView: View { var body: some View { PhaseAnimator([false,true], trigger: foo) { flash in ZStack { Capsule() .foregroundStyle(flash ? .red : .green) CustomCanvas() .foregroundStyle(flash ? .black : .white) } } animation: { flash in return .linear(duration: 0.5); } };
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’25
Reply to Error Uploading App: 'A required agreement is missing or has expired'
my Apple Developer Program contract is active until 2026 Well I guess you’ve paid until next year, but that doesn’t necessarily mean that you’ve clicked “accept” on all the required agreements. (You will need to click on updated agreements several times each year.) Go to the website and look for things that you need to click through. It’s unfortunate that the message is not more specific.
Jan ’25
Reply to App's domain being blocked/rerouted by Apple
Presumably they have a transparent proxy/cache. This is not unusual for large corporate environments - or indeed whole countries. Typically they install additional SSL root certs on the corporate devices so that they trust the proxy, which impersonates your server. How exactly is the SSL failing? Are you doing your networking? Do you have some additional checking or non-default SSL settings?
Jan ’25
Reply to How is an iOS app on the App Store able to detect other apps?!?!
"SpyBuster performs data analysis using standard AppStore API provided by Apple." That's surprising, if true. I guess there is a StoreKit API that can be abused, or something. My previous guess was that it was able to explore the filesystem to discover other installed apps. In any case, I don't believe the app should be on the store. I did wonder if it would disappear after this thread was posted, but it hasn't. App Review should be embarrassed. Do you think its anti-Russian theme might have some bearing on why it has been accepted? Would I get approved if I created a similar app that claimed to identify apps created in the USA?
Topic: Privacy & Security SubTopic: General Tags:
Jan ’25
Reply to Clarification on Opening Main App from Share Extension and App Store Submission
My recollection from a few years ago is that calling this from the wrong sort of extension doesn’t work on iOS, i.e. it does nothing or there is a run-time error or something. Does it actually work for you? You can find code that achieves this in some indirect way, i.e. by traversing the view hierarchy to find some object with a “normal” openURL method. This could result in app review issues - if they discovered it. There are apps on the store that do this.
Topic: App & System Services SubTopic: General Tags:
Jan ’25