WidgetKit

RSS for tag

Show relevant, glanceable content from your app on the iOS Home screen, iOS Lock screen, in macOS Notification Center, and as complications on Apple Watch.

WidgetKit Documentation

Posts under WidgetKit tag

136 Posts
Sort by:
Post not yet marked as solved
0 Replies
418 Views
Is there any way to modify the configurationDisplayName, description, or supportedFamilies properties, or are they essentially fixed per app version in the App Store? struct MyWidget: Widget { 		var body: some WidgetConfiguration { 				StaticConfiguration(...) { ... } 				.configurationDisplayName("foo") 				.description("bar") 				.supportedFamilies([.systemSmall, .systemMedium]) 		} } Eg, say if the user reaches an "expert" level in a game, only then do I want to make the .systemLarge size available to them. In such a case, I'd like to modify the supportedFamilies property and not have them essentially fixed in the binary. In my testing, it seems that the widget body code is only ever run once.
Posted
by
Post marked as solved
18 Replies
28k Views
SwiftUI previews don't seem to work in Xcode 12, beta 5, when using Firebase Analytics. The app builds and runs fine to simulator or device, but fails generating SwiftUI preview for a widget with the following message: ld: in /Users/../.../Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRAnalyticsConnector_e321ed8e3db06efc9803f6c008e67a34.o), building for iOS Simulator, but linking in object file built for iOS, file '/Users/.../.../Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector' for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) It was working fine in beta 4. Anyone else seen this? Any ideas?
Posted
by
Post not yet marked as solved
6 Replies
1.6k Views
When I run my widget from xcode I see getTimeline is called twice for some reason. It's called the first time, then after it returns a timeline it's called again. The logs have the following message: "-[EXSwiftUI_Subsystem beginUsing:withBundle:] unexpectedly called multiple times." It takes about 0.5 seconds for the first getTimeline call to return so it doesn't seem like the OS should try to call this method again so quickly (my timeline entries all have times in the future so they shouldn't request the widget to load immediately) Is this a bug, or expected? Seems to happen every time I run the widget.
Posted
by
Post not yet marked as solved
0 Replies
1.3k Views
Is there any way to “reset” the ios14 photo widget Can't figure out how to add photos to the photo widget on my phone. It just says "No content available" and when I tap the widget, it takes me to photos with no option to add a photo to the widget. There's also no option when you tap and hold the widget.
Posted
by
Post not yet marked as solved
13 Replies
3.8k Views
My iOS 14 home screen widget intermittently flickers in the widget gallery view. This happens sometimes when I run the widget from the simulator and sometimes happens in production. It seems like the widget is failing to instantiate before any of my code is run. I'm not able to hit any breakpoints. Has anyone seen this before?
Posted
by
Post not yet marked as solved
2 Replies
757 Views
Hello. I am creating a widget for my existing app. The main app uses a two color linear gradient throughout and I want the widget to do the same. Black at the top and my custom color of #06539F (ANCBlue). So, I create a custom color set in assets named ANCBlue with the above hex code. Then, I create an extension file: "import SwiftUI struct ColorManager { static let ancBlue = Color("ANCBlue") }" I then put this line of code in my WidgetEntryView: ".background(LinearGradient(gradient: Gradient(colors: [.black, ColorManager.ancBlue]), startPoint: .top, endPoint: .bottom))" This produces my gradient as black and green, not my wanted colors of black and ANCBlue. For the life of me, I cannot figure out why Xcode is changing the custom blue color (ANCBlue) into a green color. If I change the above line to just a solid background using my custom blue color, it shows just fine. Change it back to gradient with black and my custom blue, and the blue displays as green. Please help!
Posted
by
Post not yet marked as solved
2 Replies
1.8k Views
I have a in-house framework that I share between the main app and the widget. The framework contains some localized strings. These strings show up in correct language in the main app but on the widget they only show up in English. I'm guessing the localized strings from the framework are not getting bundled in the widget extension. Anybody with the same problem?
Posted
by
Post not yet marked as solved
5 Replies
1.6k Views
Anyone know how to solve this error? I have no idea why it's happening because I'm not using NSFileHandle or anything like that at all, my widget is super simple: makes an API call, processes it with SwiftyJSON, and displays very simple data. Thanks in advance
Posted
by
Post not yet marked as solved
2 Replies
683 Views
Hello there, I'm currently trying to develop a widget for iOS 14 and wonder if developers can create their own Widget in Smart Stack mode beside of .systemSmall, .systemMedium, .systemLarge ? And one more question that all of tutorial video in WWDC only make widget with SwiftUI App (passing data between them). Did anyone know how to intergrate it with an UIKit application? Thank in advance.
Posted
by
Post not yet marked as solved
1 Replies
198 Views
Hi, I want to query the user's current location from my widget, so I added have the 'NSWidgetWantsLocation' key in my widget's Info.plist, and added the code to find the location with CLLocationManager. But now if I launch the app for the very first time, before I even interact with the widget or do anything else, I start seeing the location permissions prompt which says "Allow <MyApp> to use your location". If I ignore it for a few seconds, the prompt goes away, but it's back the next time the app launches. It makes for a poor user experience for users who just download the app to try it out, and might not care about the widget at all. Why would this be happening? Does the widget run in the background even if the user never even launched the widget-picker mode? How would I know when the user *has* opened the widget, so I can see if I need to ask for location permissions or not? Here's what I've tried: deleting the app, and then resetting Privacy prompts (same problem) setting 'NSWidgetWantsLocation' to No stops the prompt from showing up, but defeats the purpose of finding the user's location Thanks for the help.
Posted
by
Post not yet marked as solved
5 Replies
1.1k Views
Hi, I have added widgets to my iOS app and I would like to make this feature only accessible to "pro" users that have made a non-consumable in-app purchase. Currently, I am doing the following: I store an "isUnlocked" property in the Keychain after the purchase is made I read data to be displayed in the widget and here I also query the Keychain and store whether the widget is unlocked I have no refresh policy, but only change the widget data on a significant time change a different view is displayed when the app is locked Some dummy code snippets: func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) { &#9;&#9;let entry = readContents() &#9;&#9;let timeline = Timeline(entries: [entry], policy: .never) &#9;&#9;completion(timeline) } struct WidgetEntryView: View { &#9;&#9;let entry: Provider.Entry     @Environment(\.widgetFamily) var family     @ViewBuilder     var body: some View {         switch family {         case .systemSmall:             if !entry.isUnlocked {                 LockedWidgetView()             } else if let event = entry.event {                 SmallWidgetEventView(event: event)             } else {                 NoDataWidgetView()             } ... func applicationSignificantTimeChange(_ application: UIApplication) { &#9;&#9;if #available(iOS 14.0, *) { &#9;&#9;&#9;&#9;WidgetCenter.shared.reloadAllTimelines() &#9;&#9;} ... However, 2 unexpected things happen: the view is refreshed intraday (not only at midnight i.e. at significant time change) sometimes the LockedWidgetView is displayed. Especially the latter is problematic, because it gives false information to a user that has already made the in-app purchase. How can I achieve my goal of only displaying info when the user has made the in-app purchase? Thanks in advance. P.S. Although it would not have my preference, I would also find it acceptable if the widget is only shown as option to add once the purchase is made. In other words, I was considering changing the Widget itself: struct MyWidget: Widget {     private var supportedFamilies: [WidgetFamily] = isUnlocked() ? [.systemSmall, .systemMedium] : [] but I believe I cannot re-initialise the widget from the app when the user makes the in-app purchase, because the only refresh option that I have is WidgetCenter.shared.reloadAllTimelines()
Posted
by
Post not yet marked as solved
7 Replies
2.0k Views
I had to create a separate thread for the problem I'm facing with WidgetKit. Environment: Xcode 12.0.1 iOS 14.0 App targeting iOS 10 Widget targeting iOS 14 Intents Extension targeting iOS 10 • I have created Intents Extension. • Created Intents Definition file in Widget target, added it to all the three targets (app, widget, intents extension).  • Declared conformance to the intent handling protocol in IntentHandler (Intents Extension). • Set up Intent Timeline Provider in Widget target.  • Added Siri to the app capabilities. If I go to Edit widget -> tap on a dynamic option it says: No options were provided for this parameter. Intents Extension provides data, but I'm not sure how iOS wires the Intents Extension and widget. From what I see I'm sure that my code inside IntentsHandler.swift is never called.
Posted
by
Post not yet marked as solved
7 Replies
1.2k Views
On the crash reports, I am getting a lot of crashes with this crash report for two iOS 14 Widgets: Foundation&#9;&#9;_NSFileHandleRaiseOperationException .... SwiftUI&#9;&#9;&#9; FileArchiveWriter.AppendByes(_size:) .... My Widget&#9;&#9;&#9; closure #1 in MyTimelineProver.getTimeline(in:completion:) When checked within the project, this happens in: func getTimeline(in context: Self.Context, completion: @escaping (Timeline<Self.Entry>) -> Void) I have one timeline that asked to update every 5 mins.
Posted
by
Post not yet marked as solved
1 Replies
396 Views
I've used the sample provided from within XCode (12.3 Beta), which fails with the following error: 2020-11-13 06:30:11.488477+0000 widgetExtension[3834:124572] [subsystems] Bootstrapping; external subsystem UIKit_PKSubsystem refused setup Is there a way to get more detailed debug info?
Posted
by
Post not yet marked as solved
2 Replies
823 Views
Have been days I am stuck on this, really hoping someone can help. I have added Widget to my existing AppKit project (macOS), and all works fine. However when I try to archive, it keeps failing at this error: 2020-11-14 23:58:29 +0000&#9;/var/folders/gv/cqghcvl50690hwhk3bbpf7pr0000gn/T/XcodeDistPipeline.~~~HAVL4T/Root/Applications/XXXX.app/Contents/PlugIns/Mac WidgetExtension.appex: replacing existing signature 2020-11-14 23:58:29 +0000&#9;/var/folders/gv/cqghcvl50690hwhk3bbpf7pr0000gn/T/XcodeDistPipeline.~~~HAVL4T/Root/Applications/XXXX.app/Contents/PlugIns/Mac WidgetExtension.appex: code object is not signed at all 2020-11-14 23:58:29 +0000&#9;/usr/bin/codesign exited with 1 Have tried: Clearing and removing all certificates Upgrading to Big Sur Removed and recreate Widget Target Manually creating provisioning profiles
Posted
by
Post marked as solved
3 Replies
953 Views
The app uses Core Data + CloudKit. When the app gets launched WidgetKit file fetches correct entries from Core Data but when I add new entries to Core Data from the main app and call WidgetCenter.shared.reloadTimelines() updated entries don't get fetched and old data is displayed inside the widget. Main app and Widget target have the same App group, iCloud capability enabled for both targets. When I call WidgetCenter.shared.reloadTimelines() from the Main app Widget reloads (timer added to Widget view sets to zero) but fetch from Core Data doesn't return newly added entries. Then I restart the app and correct entries get fetched. Why doesn't it fetch correct entries when WidgetCenter.shared.reloadTimelines() gets called and only works when app is relaunched? Widget's code: import WidgetKit import SwiftUI import CoreData struct Provider: TimelineProvider { &#9;&#9;func placeholder(in context: Context) -> HabitsEntry { &#9;&#9;&#9;&#9;HabitsEntry(date: Date(), habitsCount: 0) &#9;&#9;} &#9;&#9;func getSnapshot(in context: Context, completion: @escaping (HabitsEntry) -> ()) { &#9;&#9;&#9;&#9;let entry = HabitsEntry(date: Date(), habitsCount: 0) &#9;&#9;&#9;&#9;completion(entry) &#9;&#9;} &#9;&#9;func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;let managedObjectContext = Storage.viewContext &#9;&#9;&#9;&#9;let request = NSFetchRequest<NSFetchRequestResult>(entityName: "DailyHabit") &#9;&#9;&#9;&#9;let predicate = Storage.getCurrentDatePredicate() &#9;&#9;&#9;&#9;request.predicate = predicate &#9;&#9;&#9;&#9;var habits = 0 &#9;&#9;&#9;&#9;do { habits = try managedObjectContext.count(for: request)&#9;} &#9;&#9;&#9;&#9;catch let error as NSError {print ("Could not fetch \(error), \(error.userInfo)")} &#9;&#9;&#9;&#9;let entry = [HabitsEntry(date: Date(), habitsCount: habits)] &#9;&#9;&#9;&#9;let timeline = Timeline(entries: entry, policy: .never) &#9;&#9;&#9;&#9;completion(timeline) &#9;&#9;} } struct HabitsEntry: TimelineEntry { &#9;&#9;let date: Date &#9;&#9;var habitsCount: Int } struct HabitsHomeWidgetEntryView : View { &#9;&#9;var entry: Provider.Entry &#9;&#9;var body: some View { &#9;&#9;&#9;Text(entry.date, style: .timer) &#9;&#9;&#9;Text("There are \(entry.habitsCount) daily habits") &#9;&#9;} } @main struct HabitsHomeWidget: Widget { &#9;&#9;let kind: String = "HabitsHomeWidget" &#9;&#9;var body: some WidgetConfiguration { &#9;&#9;&#9;&#9;StaticConfiguration(kind: kind, provider: Provider()) { entry in &#9;&#9;&#9;&#9;&#9;&#9;HabitsHomeWidgetEntryView(entry: entry) &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;.configurationDisplayName("My Widget") &#9;&#9;&#9;&#9;.description("This is an example widget.") &#9;&#9;} }&#9; Here is the code for Core Data: import UIKit import CoreData import WidgetKit class Storage { &#9; &#9;static let shared = Storage() &#9; &#9;static var persistentContainer: NSPersistentContainer { &#9;&#9;return Storage.shared.persistentContainer &#9;} &#9; &#9;static var viewContext: NSManagedObjectContext { &#9;&#9;return persistentContainer.viewContext &#9;} &#9; &#9;lazy var persistentContainer: NSPersistentContainer = { &#9;&#9;let container: NSPersistentContainer &#9;&#9; &#9;&#9;let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupName)! &#9;&#9;let storeURL = containerURL.appendingPathComponent("NoRegrets.sqlite") &#9;&#9;let description = NSPersistentStoreDescription(url: storeURL) &#9;&#9;if isICloudContainerAvailable { &#9;&#9;&#9;container = NSPersistentCloudKitContainer(name: Constants.persistentContainerName) &#9;&#9;} else { &#9;&#9;&#9;container = NSPersistentContainer(name: Constants.persistentContainerName) &#9;&#9;} &#9;&#9;description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) &#9;&#9;description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) &#9;&#9;description.shouldMigrateStoreAutomatically = true &#9;&#9;description.shouldInferMappingModelAutomatically = true &#9;&#9;let storeDescription = description &#9;&#9; &#9;&#9;container.persistentStoreDescriptions = [storeDescription] &#9;&#9; &#9;&#9;container.loadPersistentStores(completionHandler: { (storeDescription, error) in &#9;&#9;&#9;if let error = error as NSError? { &#9;&#9;&#9;&#9;return &#9;&#9;&#9;} &#9;&#9;}) &#9;&#9; &#9;&#9;container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy &#9;&#9;container.viewContext.automaticallyMergesChangesFromParent = true &#9;&#9; &#9;&#9;do { &#9;&#9;&#9;try container.viewContext.setQueryGenerationFrom(.current) &#9;&#9;} catch { &#9;&#9;&#9;print("Failed to pin viewContext to the current generation: \(error)") &#9;&#9;} &#9;&#9;return container &#9;}() &#9; &#9;var isICloudContainerAvailable: Bool { &#9;&#9;FileManager.default.ubiquityIdentityToken != nil &#9;} &#9; &#9;// MARK: - Core Data Saving support &#9;func saveContext() { &#9;&#9;let context = persistentContainer.viewContext &#9;&#9;if context.hasChanges { &#9;&#9;&#9;do { &#9;&#9;&#9;&#9;try context.save() &#9;&#9;&#9;&#9; &#9;&#9;&#9;} catch { &#9;&#9;&#9;&#9;let nserror = error as NSError &#9;&#9;&#9;&#9;print("Saving error: \(nserror)") &#9;&#9;&#9;} &#9;&#9;} &#9;} } // MARK: - Helper methods extension Storage { &#9;func getCurrentUser() -> User? { &#9;&#9;let fetchRequest = User.createFetchRequest() &#9;&#9;fetchRequest.fetchLimit = 1 &#9;&#9;fetchRequest.sortDescriptors = [NSSortDescriptor(key: "objectID", ascending: false)] &#9;&#9; &#9;&#9;let user = try? Storage.viewContext.fetch(fetchRequest).first &#9;&#9;return user &#9;} &#9; &#9;class func getCurrentDatePredicate() -> NSPredicate { &#9;&#9;var calendar = Calendar.current &#9;&#9;calendar.timeZone = NSTimeZone.local &#9;&#9;let dateFrom = calendar.startOfDay(for: Date()) &#9;&#9;let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom) &#9;&#9;let fromPredicate = NSPredicate(format: "date >= %@", dateFrom as NSDate) &#9;&#9;let toPredicate = NSPredicate(format: "date < %@", dateTo! as NSDate) &#9;&#9;return NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate]) &#9;} }
Posted
by
Post not yet marked as solved
1 Replies
467 Views
I feel like this should be a pretty common problem with a pretty simple answer, but has anyone encountered a problem where your app's widget is not available on a device where you've been testing a dev version of your app as well as installing the App Store version? So what I mean is, on my iPhone, I'm often testing daily builds of our app, and I'm also installing our app from the App Store. At some point, this combo results in our app's widget being unavailable in the list of widgets on my iPhone. I've tried uninstalling dev builds, App Store releases, and so on, but the widget never comes back on a new install. Looking for a magic combo here, I guess, to clear some mystery widget registry or something.
Posted
by
Post marked as solved
8 Replies
861 Views
I am trying to make a circular progress bar for my widget, I am using this code to do so. On the base app content view, everything comes out how I want it to. But when I try the same view on my widget, Circle().trim seems to not allow a drawing to happen and the circle disappears completely. I have seen a couple of posts about this on the forums. I am currently running on Xcode 12.3      ZStack{       Color(red: 0, green: 0, blue: 0)       ZStack {         Circle()           .rotation(.degrees(112))           .trim(from:0.0, to: 0.87)           .stroke(style: StrokeStyle(lineWidth: 8.0, lineCap: .round))           .opacity(0.3)           .foregroundColor(Color.gray)           .frame(width: 120, height: 120, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)                   Circle()           .rotation(.degrees(112))           .trim(from:0.0, to: 0.2)           .stroke(style: StrokeStyle(lineWidth: 8.0, lineCap: .round, lineJoin: .round))           .foregroundColor(Color.white)           .frame(width: 120, height: 120, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)                             }       .padding()   }
Posted
by
Post not yet marked as solved
2 Replies
1.2k Views
Project structure is: App target + widget extension + widget intent extension All share a common appgroup group.com.x.y and all file handling is done using FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.x.y") so that only the shared container is used. Using the Main app target, a font "Chewy-Regular.ttf" is downloaded and saved to the shared AppGroup container. Font can now be loaded via CTFontManagerRegisterFontsForURL and displayed in a Main App Text view Text("Testing...").font(Font.custom("Chewy-Regular", size: 20)) Now add a Widgetkit widget instance that uses this font. In 'getTimeLine() and getSnapShot() of IntentTimelineProvider we load the font again via CTFontManagerRegisterFontsForURL (this needs to happen again probably because widget runs in a separate process from the main app?). On simulator, the widget will show the correct font. BUT On iPhone7 real device, the widget will show the 'redacted placeholder view'. It seems that something is crashing. I see in the device console : error 14:39:07.567120-0800 chronod No configuration found for configured widget identifier: D9BF75EE-4A04-441A-8C85-1507F7ECE379 fault 14:39:07.625600-0800 widgetxExtension -[EXSwiftUI_Subsystem beginUsing:withBundle:] unexpectedly called multiple times. error 14:39:07.672733-0800 chronod Encountered an error reading the view archive for <private>; error: <private> error 14:39:07.672799-0800 chronod [co.appevolve.onewidget.widgetx:widgetx:small:1536744920620481560@148.0/148.0/20.2] reload: could not decode view error 14:39:07.674984-0800 kernel Sandbox: chronod(2128) deny(1) file-read-metadata /private/var/mobile/Containers/Shared/AppGroup/9B524570-1765-4C24-9E0C-15BC3982F0DC/downloadedFonts/Chewy/Chewy-Regular.ttf error 14:39:07.675762-0800 kernel Sandbox: chronod(2128) deny(1) file-read-data /private/var/mobile/Containers/Shared/AppGroup/9B524570-1765-4C24-9E0C-15BC3982F0DC/downloadedFonts/Chewy/Chewy-Regular.ttf error 14:39:07.708914-0800 chronod [u 8D2C83B3-A6CB-432E-A9D4-9BC8F7056B10:m (null)] [<private>(<private>)] Connection to plugin invalidated while in use. fault 14:39:07.710284-0800 widgetxExtension -[EXSwiftUI_Subsystem beginUsing:withBundle:] unexpectedly called multiple times. error 14:39:07.803468-0800 chronod Encountered an error reading the view archive for <private>; error: <private> It seems that it's a permission issue, and the textview can't access the font file it needs when the widget is rendering. Notes: 1) Font is definitely registered because I can see them in for fontFamily in UIFont.familyNames {             for fontName in UIFont.fontNames(forFamilyName: fontFamily) {                 print(fontName) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;... in both the Main App target and the Widget Extension target 2) If I make make the font part of the app bundle and add to 'Fonts provided by application' , the are loaded absolutely fine in the Main App and the Widget on simulator and iPhone 7 real device. 3) I do see this error sometimes in the Widget extension target log, don't know if it's related. widgetxExtension[1385:254599] [User Defaults] Couldn't read values in CFPrefsPlistSource<0x28375b880> (Domain: group.co.appevolve.onewidget, User: kCFPreferencesAnyUser, ByHost: Yes, Container: (null), Contents Need Refresh: Yes): Using kCFPreferencesAnyUser with a container is only allowed for System Containers, detaching from cfprefsd 4) I suspected something to do with app groups, so I tried to copy the font into the Widget Extension container and load from there, but had the same result. Please help! Thank you.
Posted
by