Post

Replies

Boosts

Views

Activity

Reply to redacted(reason: .privacy) not working as expected
I use this code for the same situation as you. My iOS app lets the user choose whether to hide info on the Watch screen. This is how I determine whether stuff should be hidden. Pass in your redactionReasons environment variable: func getWidgetHideInfo(_ redactionReasons: RedactionReasons) -> Bool { // Convenience method to decide whether or not to hide sensitive info when the system wants to.   // It is overridden by the iOS app setting: "Show information when device is locked/inactive". return ((redactionReasons.contains(.privacy) || redactionReasons.contains(.placeholder)) && defaultsGetSettingsWidgetPrivacy() == false) } defaultsGetSettingsWidgetPrivacy() gets the switch value from defaults; you may have it somewhere else. When the switch is off, it's false, and it means the user wants to hide their info, so this method is saying, when the system wants to hide stuff (.privacy) or the user wants to hide stuff, return true, meaning yes we want to hide this data. Put this code somewhere: extension View { /// Applies a modifier to a view conditionally. /// /// - Parameters: ///   - condition: The condition to determine if the content should be applied. ///   - content: The modifier to apply to the view. /// - Returns: The modified view. @ViewBuilder func modifier<T: View>( if condition: @autoclosure () -> Bool, then content: (Self) -> T ) -> some View { if condition() { content(self) } else { self } } /// Applies a modifier to a view conditionally. /// /// - Parameters: ///   - condition: The condition to determine the content to be applied. ///   - trueContent: The modifier to apply to the view if the condition passes. ///   - falseContent: The modifier to apply to the view if the condition fails. /// - Returns: The modified view. @ViewBuilder func modifier<TrueContent: View, FalseContent: View>( if condition: @autoclosure () -> Bool, then trueContent: (Self) -> TrueContent, else falseContent: (Self) -> FalseContent ) -> some View { if condition() { trueContent(self) } else { falseContent(self) } } } In your views, add a line like this so you have a variable you can use that says to hide or show the data: let hideInfo: Bool = getWidgetHideInfo(redactionReasons) And here's the fun part (if it works). Add the following modifier to something, like a Text() or an Image(), for example: Image(systemName: "arrow.left.square.fill") .font(.system(size: 32.0, weight: .regular)) .modifier(if: hideInfo) { $0.redacted(reason: .placeholder) } else: { $0.unredacted() } Here it is with hideInfo = false: And here it is with hideInfo = true:
Topic: Programming Languages SubTopic: Swift Tags:
Sep ’22
Reply to iPhone 14 Pro (and 14 Pro Max) Native Screen Size
I think you're getting the numbers mixed up. The Simulator reports these numbers: 390x844 @ 3x = 1170 x 2532 pixel resolution at 460ppi = iPhone 12, 13, 14, and 12 Pro, 13 Pro 393x852 @ 3x = 1179 x 2556-pixel resolution at 460ppi = iPhone 14 Pro My real iPhone 14 Pro device correctly reports the second line of numbers. I don't think there is an error here.
Topic: UI Frameworks SubTopic: UIKit Tags:
Sep ’22
Reply to How to read touch and accelerometer data
Three things: If the app is inactive you have a very limited set of things you can perform in the background, and I don't think recording accelerometer data is allowed. An inactive app definitely isn't going to receive touch events. As has been mentioned, that would seem very much like a key logger. You must only work with the exposed APIs. You cannot use private APIs. Any app you create that uses them will be rejected.
Topic: UI Frameworks SubTopic: UIKit Tags:
Sep ’22
Reply to WidgetKit — how to send data from Widget to main app
In my widget I have this wrapping the HStack of the main content: Link(destination: updateEventToOpenInMainApp(event.name)) { HStack { ... } .widgetURL(updateEventToOpenInMainApp(event.name)) } The updateEventToOpenInMainApp() function is this: func updateEventToOpenInMainApp(_ name: String) -> URL { let activity: NSUserActivity = NSUserActivity.init(activityType: "ViewEventIntent") activity.title = kWidgetPreviewEvent // A String: "widget_PreviewEvent:" activity.userInfo = [kWidgetPreviewEvent : name] activity.becomeCurrent() let urlString: String = kWidgetPreviewEvent + name.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)! return URL(string: urlString)! } When the widget is tapped, the url is crafted as above, and sent to the main iOS app. The iOS app then has this in the AppDelegate (Objective-C): - (BOOL)application:(UIApplication *)app openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { if([url.path hasPrefix:kWidgetPreviewEvent]) { // The prefix from earlier NSString *eventName = [[url.path stringByRemovingPercentEncoding] stringByReplacingOccurrencesOfString:kWidgetPreviewEvent withString:@""]; ... Works for me.
Topic: App & System Services SubTopic: General Tags:
Sep ’22