Post

Replies

Boosts

Views

Activity

Inconsistent Widget Behaviour Between Devices in iOS 14
Hello All, I recently launched an iOS 14 Widget for my app. In testing everything seemed a-okay but on launch I am having inconsistent behaviour. On some devices the widget loads as just black, on other devices it only loads the placeholder content and on some devices it works as intended. The behaviour exhibited, good or bad, is consistent in the Add Widget Screen and when it's added to the Home Screen. On the devices where my widget does not work, other widgets do work. The content in the Widget only changes when something is changed in the app thus I call WidgetCenter.shared.reloadAllTimelines() in the SceneDelegate when sceneWillResignActive is called. The expected behaviour is that when the user backgrounds the application the widget will update. On the devices that show black or placeholder content this Widget Center Update does not work, on the devices where it does work the update function works as expected. This is the code for my Widget:   struct ThisWeekProvider: TimelineProvider {     func placeholder(in context: Context) - ThisWeekEntry {       return ThisWeekEntry(date: Date(), thisWeekJSON: getDefaultTimeSummaryJSON())     }         func getSnapshot(in context: Context, completion: @escaping (ThisWeekEntry) - ()) {           var thisWeekData = TimeSummaryJSON()       if context.isPreview {         thisWeekData = getThisWeekData()       } else {         thisWeekData = getThisWeekData()       }           let entry = ThisWeekEntry(date: Date(), thisWeekJSON: thisWeekData)       completion(entry)     }         func getTimeline(in context: Context, completion: @escaping (TimelineEntry) - ()) {       let entries: [ThisWeekEntry] = [ThisWeekEntry(date: Date(), thisWeekJSON: getThisWeekData())]           let timeline = Timeline(entries: entries, policy: .after(entries[0].thisWeekJSON.endDate))       completion(timeline)     }   }       struct ThisWeekEntry: TimelineEntry {     let date: Date     let thisWeekJSON: TimeSummaryJSON   }       struct ThisWeekWidgetEntryView : View {     var entry: ThisWeekProvider.Entry     var body: some View {       COMMENT - Generate View       COMMENT - Use data from 'entry' to fill widget   }       struct ThisWeekWidget: Widget {     let kind: String = K.thisWeekWidget         var body: some WidgetConfiguration {       StaticConfiguration(kind: kind, provider: ThisWeekProvider()) { entry in         ThisWeekWidgetEntryView(entry: entry)       }       .configurationDisplayName("this_week_widget".localized())       .description("this_week_description".localized())       .supportedFamilies([.systemSmall])     }   } The custom data type 'TimeSummaryJSON' is as follows:   struct TimeSummaryJSON: Codable {           var labourIncome: String = "$0.00"     var equipmentIncome: String = "$0.00"     var days: String = "0"     var hours: String = "0"           var endDate: Date = Date()     var settingsFirstDayOfWeek: String = K.monday     var localeFirstDayOfWeek: Bool = false         } The custom function that retrieves the data 'getThisWeekData()' is as follows:   private func getThisWeekData() - TimeSummaryJSON {     if let encodedData = UserDefaults(suiteName: AppGroup.shared.rawValue)!.object(forKey: K.thisWeek) as? Data {       if let thisWeekJSON = try? JSONDecoder().decode(TimeSummaryJSON.self, from: encodedData) {         return checkExpiryForCurrentWeek(thisWeekJSON)       } else {         print("Decoding Error - Return Default This Week")         return getDefaultTimeSummaryJSON()       }     } else {       print("No Shared Data - Return Default This Week")       return getDefaultTimeSummaryJSON()     }   } The process of saving and retrieving the data works like this: SceneDelegate calls sceneWillResignActive Data is pulled from the Local Realm Database, calculated and saved into a TimeSummaryJSON TimeSummaryJSON is encoded and saved to a shared AppGroup WidgetCenter.shared calls reloadAllTimelines() Widget decodes JSON data from AppGroup If the JSON Decode is successful the current user data is shown in the widget, if the JSON Decode fails a default TimeSummaryJSON is sent instead I've looked over my code quite extensively and read countless forums and it seems that I am doing everything correctly. Have I missed something? Could anyone suggest why the behaviour is inconsistent between devices? I'm well and truly stuck and am not sure what to try next. Any help you can offer would be kindly appreciated. Thank you!
2
0
1.8k
Apr ’21
Weird Issue with UIDatePicker
Hello All, I've been using a UIDatePicker in my application since launch and it has been working without issue. Sometime in the past 4-6 Weeks I've had users reporting an intermittent problem where it does not work, at this stage I can not confirm if it's happening only on newer versions of the app, this shouldn't be the case as the code base has not changed at all for anything related to the UIDatePicker. I have seen it happen in the wild once on a friend's App Store Version of my app, on his iPhone he would move the UIDatePicker and the date would change in the picker view, but it wouldn't be reflected elsewhere in the app indicating that the UIDatePicker isn't sending data through to other components, in this case the UITextField. However on my device, two devices and the iOS Simulator, all on the same iOS Version, all with the latest version of the app, this issue did not occur. Code snippets are as follows: // Setup Date Picker     datePicker.datePickerMode = .date     datePicker.addTarget(self, action: #selector(AddWorkDayViewController.datePickerChanged(sender:)), for: .valueChanged)           // Set Date Picker Style     if #available(iOS 13.4, *) {       datePicker.preferredDatePickerStyle = .wheels     } else {       // Fallback on Earlier Versions     }           //Setup Date Toolbar     dateToolbar.barStyle = .default     dateToolbar.isTranslucent = true     dateToolbar.sizeToFit()     let doneButton = UIBarButtonItem(title: "done".localized(), style: .done, target: self, action: #selector(AddWorkDayViewController.doneTouched))     let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)     let todayButton = UIBarButtonItem(title: "today".localized(), style: .done, target: self, action: #selector(AddWorkDayViewController.todayTouched))     dateToolbar.setItems([todayButton, spaceButton, doneButton], animated: false)     dateToolbar.isUserInteractionEnabled = true           // Assign Date Picker and Date Toolbar to Date Label     dateLabel.inputView = datePicker     dateLabel.inputAccessoryView = dateToolbar // Called When User Changes UIDatePicker @objc func datePickerChanged(sender: UIDatePicker) {     let pickerDate = sender.date     date = pickerDate     let dateFormatted = date.toFormat(settings.dateFormatLong)     dateTextField.text = dateFormatted   } Any ideas on where to start with this? Given it happens on some devices and not others it's quite troublesome to diagnose. On the device I saw it happen on I checked accessibility settings, rebooted the device, etc. and could not figure out why it was behaving this way. Thank you!
1
0
1.1k
Sep ’22
Allow Display Mode Changes
When you connect an external display via USB-C to an iPad, that displays shows in iPadOS via Settings -> Display and Brightness -> Name of Display. There is an option called 'Allow Display Mode Changes' for an external display which is described as follows: When this is on, the display mode will change to match the dynamic range and frame rate of the content you're viewing. This may result in flickering or long periods of black whenever content changes. Does anyone know how this functionality works and how to support it for an iPadOS App? In my tests the iPad always outputs at a frame rate of 60fps or sometimes 59.94fps. If the video I am playing back from an AVPlayer is at 25fps the external display stays at 60fps both with 'Allow Display Mode Changes' toggled on/off. Given that it's meant to 'match frame rate of content' I would expect the external display to change from 60fps -> 25fps. I can not find any documentation about this feature and what AV Frameworks it talks to or gets it's frame rate information from. If anyone has any idea or has experimented with it and learnt something that would be much appreciated.
0
0
832
Nov ’23
iOS Device Support Keylogger
Hello, I recently ran a virus/malware scan on my dev machine using ClamAV, this was run via macOS Terminal using the 'clamscan' function. Everything came back okay except a keylogger in the ProVideo Framework for physical iOS Test Devices. Please see below for 'clamscan' output: /Users/username/Library/Developer/Xcode/iOS DeviceSupport/iPad8,11 17.4 (21E219)/Symbols/System/Library/PrivateFrameworks/ProVideo.framework/ProVideo: Unix.Keylogger.Macos-10023932-0 FOUND My understanding is that '/Library/Developer/Xcode/iOS DeviceSupport/' is where Xcode keeps the files related to physical test devices that are required for debug. There were 3 Instances of this keylogger, all of which corresponded to physical devices I own and iOS Versions that I have installed / were installed. Can anyone verify if 'Unix.Keylogger.Macos-10023932-0' is a valid file that ClamAV is incorrectly detecting as malicious? If it is a valid debug file provided by Apple, it seems strange that it's located in the ProVideo Framework. I couldn't find any documentation online about this so any information would be appreciated. At this stage I have deleted the contents of '/Library/Developer/Xcode/iOS DeviceSupport/', my understanding is that these symbols are only transferred to the system when I test software via Xcode on a physical device and will not reproduce until I do that again. To me it's unclear if perhaps this keylogger is present on my iOS Device and is being transferred to the Mac via Xcode? Or somehow it is just appearing in this folder? Thanks!
2
0
864
Apr ’24
NavigationView Issues in iOS 18 Beta 3
I have a SwiftUI NavigationView that is presented inside of a UIHostingController. In iOS 17 and earlier everything looks and works okay. I opened up my project in iOS 18 Beta 3 via the iOS Simulator running on macOS Sequoia, the NavigationView just displays a blank view with a Sidebar Button in the top left outside of the safe area. If I comment out the NavigationView and just display my 'root view' everything looks as it should but navigation is broken as it uses NavigationLink which of course doesn't work without NavigationView. I still target iOS 14 as Minimum Version so swapping completely to NavigationStack isn't possible given that NavigationView is deprecated from iOS 16 onwards. I tried to implement a solution with NavigationStack, it works but my UI displays outside of the safe area. I have a button towards the bottom of the screen which now overlaps the system line at the bottom of the screen. The Back Button in the Navigation Stack now sits behind the time in the top left. I do not have 'ignoreSafeArea' applied anywhere in this View Hierarchy. It looks like that is being applied by 'NavigationStack' on it's own accord. Is this happening to anyone else? Is this a known bug? I could not see this in the release notes if it is known. Thanks!
9
0
1.9k
Jul ’24