Would something like this format help?
import WidgetKit
import SwiftUI
@main
struct AppWidgets {
// Combine widgets in this way to prevent crashes.
static func main() {
if #available(iOSApplicationExtension 18.0, *) {
WidgetsBundle18.main()
} else {
WidgetsBundle17.main()
}
}
}
@available(iOSApplicationExtension 18.0, *)
struct WidgetsBundle18: WidgetBundle {
var body: some Widget {
NewWidget()
}
}
struct WidgetsBundle17: WidgetBundle {
var body: some Widget {
OldWidget()
}
}
Post
Replies
Boosts
Views
Activity
Just expanding on my previous comment...
Apple Watch really lags behind in this area. Although it does record HRV data it simply doesn’t record enough to provide effective insights and trends to users. My app users are CONSTANTLY asking me how to record more HRV data, how to trigger a recording from my app and how to track it more effectively. This is all very difficult in WatchOS currently.
I've filed a feedback FB13880126 and mentioned it at two WWDC labs.
🙏🙏 This might get picked up this summer.
With all the new Intent based push and APIs... this seems like a glaring omission for developers who originally made more straightforward StaticConfiguration widgets and now want to upgrade them to more advanced and configurable IntentConfiguration ones.
It seems that if I keep the same “kind” String identifier for the widget, they do migrate but only after a restart of the iPhone…. Until that point they just freeze and hang. This isn't really something I can ask my users to do....
I've filed a feedback: FB13880020
🙏🙏 This might get fixed for iOS 18.
@Thuri88 This looks like a fantastic suggestion, Thank You!
I'll go ahead and implement this and do some testing.
You mention Apple's activity rings Lock Screen widget implementing this.... I'm fairly sure I've observed it updating throughout the day without the iPhone being unlocked at all. There's also then the problem of StandBy mode and Widget on Mac which also can't update whilst your iPhone is locked.... and lots of my users would love to see their Health data in widgets on their Mac.
I've filed a feedback again on this: FB13879739
🙏🙏 A solution may be offered one day.
For completeness I've filed another feedback here as this issue still plagues my users running WatchOS 9.6.3
New Feedback Number: FB13879553
Previous feedback: FB11989396, FB12818520, FB12818485
🙏🙏 This may one day get solved...
I've submit three past feedback (FB13879424 most recent) for this and mentioned it at three WWDC sessions.
🙏🙏 for a solution soon!
It's good practice to always write
@State private var
This is because you should not declare a view and set the state within it's initialiser, it can cause the value to change undesirably when the view is redrawn.
Use @Binding if you want to bind a variable to a view and make changes to it inside and outside of that view.
I believe this may have changed with WatchOS 11.
Presumable this was done to allow for the new Vitals app and also Workout training loads to look at the longer 28 day trends and identify differences.
I'll do some testing and try to come back with some actual available timescales for this against Health types:
Heart Rate
HRV
Blood Oxygen Saturation
Body Temperature
Steps
Activity
Workouts
Might take me a few weeks incase I have to have had WatchOS 11 installed for the elapsed time period to see the data!
No response. I've not seen so many reports from users of rat duplicate ClockKit and WidgetKit complications being offered.
However, I'm still seeing rendering issues for complications in the Watch app Face Gallery tab. Some render, some don't, there seems to be no rhyme or reason.
Tested on latest WatchOS 10.5 and iOS 17.5.1
I'm still seeing a lot of these crashes in devices running iOS 17 including 17.4 & 17.5.
There doesn't seem to be any problems with users on iOS 16.
OS Version: iPhone OS 17.4.1 (21E236)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Codes: 0x0000000000000001, 0x0000000000000000
VM Region Info: 0 is not in any region. Bytes before following region: 4373921792
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT 104b4c000-104c88000 [ 1264K] r-x/r-x SM=COW /var/containers/Bundle/Application/89D41909-EA37-4C14-87A4-D7CB78F7E83E/<App_Name>.app/<App_Name>
Termination Reason: SIGNAL 11 Segmentation fault: 11
Terminating Process: exc handler [606]
Triggered by Thread: 0
Thread 0 name:
Thread 0 Crashed:
0 RenderBox 0x000000020450ff64 RB::Heap::alloc_slow(unsigned long, unsigned long) + 252 (heap.cc:123)
1 RenderBox 0x0000000204523088 RB::Coverage::Glyphs::Glyphs(RB::Heap&, CGFont*, unsigned int, unsigned short const*, float vector[2] const*, unsigned int, float vector[2], unsigned int) + 252 (coverage-glyphs.mm:82)
2 RenderBox 0x00000002045230d8 RB::Coverage::Glyphs::Glyphs(RB::Coverage::Glyphs const&, RB::Heap&) + 52 (coverage-glyphs.mm:95)
3 RenderBox 0x000000020455a7dc RB::DisplayList::GenericItem1<RB::Coverage::Glyphs, RB::Fill::Color>::GenericItem1(RB::Heap&, RB::Coverage::Glyphs const&, RB::Fill::Color const&, RB::AffineTransform const*, float, RB::BlendMode, ... + 112 (display-list.h:1081)
4 RenderBox 0x000000020455b438 RB::DisplayList::GenericItem<RB::Coverage::Glyphs, RB::Fill::Color>* RB::Heap::emplace<RB::DisplayList::GenericItem<RB::Coverage::Glyphs, RB::Fill::Color>, RB::Heap&, RB::Coverage::Glyphs const&, R... + 116 (heap.h:33)
5 RenderBox 0x000000020455a86c RB::DisplayList::GenericItem<RB::Coverage::Glyphs, RB::Fill::Color>::copy(RB::DisplayList&, unsigned int) const + 76 (display-list.h:2235)
6 RenderBox 0x00000002045ae7fc RB::DisplayList::draw(RB::DisplayList::Contents const&, RB::DisplayList::State&, float, RB::DisplayListPredicate::Invertible const*, void*) + 800 (display-list.mm:1822)
7 RenderBox 0x0000000204545478 -[RBDisplayListPredicate filteringDisplayList:] + 104 (RBDisplayList.mm:2205)
8 SwiftUI 0x00000001954a4fcc ResolvedStyledText.layers(for:renderer:deviceScale:) + 132 (Text+View.swift:1413)
9 SwiftUI 0x000000019554ba28 _ShapeStyle_RenderedShape.renderKeyedText(_:style:name:layers:) + 304 (ShapeStyleRendering.swift:730)
10 SwiftUI 0x0000000195546ec8 _ShapeStyle_RenderedShape.renderItem(name:styles:layers:) + 404 (ShapeStyleRendering.swift:95)
11 SwiftUI 0x0000000194fd0428 specialized ShapeStyledDisplayList.updateValue() + 916 (ShapeStyledLeafView.swift:210)
12 SwiftUI 0x00000001951043d4 specialized implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 24 (<compiler-generated>:0)
13 AttributeGraph 0x00000001b9834240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
14 AttributeGraph 0x00000001b982af38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
15 AttributeGraph 0x00000001b9832538 AG::Graph::value_ref(AG::AttributeID, unsigned int, AGSwiftMetadata const*, unsigned char&) + 288 (ag-graph.cc:1201)
16 AttributeGraph 0x00000001b9835470 AGGraphGetWeakValue + 388 (AGGraph.mm:735)
17 SwiftUI 0x000000019580dfb8 ViewGraph.displayList() + 44 (ViewGraph.swift:766)
18 SwiftUI 0x00000001962c3a4c closure #2 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 2252 (ViewRendererHost.swift:259)
19 SwiftUI 0x00000001962c3028 closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 660 (ViewRendererHost.swift:235)
20 SwiftUI 0x00000001962c1170 ViewRendererHost.render(interval:updateDisplayList:) + 408 (<compiler-generated>:0)
21 SwiftUI 0x0000000196331164 _UIHostingView.layoutSubviews() + 332 (UIHostingView.swift:1127)
22 SwiftUI 0x00000001963311c4 @objc _UIHostingView.layoutSubviews() + 36 (<compiler-generated>:0)
23 UIKitCore 0x00000001930050f8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1528 (UIView.m:20041)
24 QuartzCore 0x000000019242fe30 CA::Layer::layout_if_needed(CA::Transaction*) + 504 (CALayer.mm:10816)
25 QuartzCore 0x000000019242f9b4 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 148 (CALayer.mm:2598)
26 QuartzCore 0x0000000192435bb4 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 464 (CAContextInternal.mm:2760)
27 QuartzCore 0x000000019242f1bc CA::Transaction::commit() + 648 (CATransactionInternal.mm:432)
28 QuartzCore 0x000000019242ee64 CA::Transaction::flush_as_runloop_observer(bool) + 88 (CATransactionInternal.mm:942)
29 UIKitCore 0x000000019307d260 _UIApplicationFlushCATransaction + 52 (UIApplication.m:3160)
30 UIKitCore 0x000000019307cd78 _UIUpdateSequenceRun + 84 (_UIUpdateSequence.mm:119)
31 UIKitCore 0x000000019307c468 schedulerStepScheduledMainSection + 144 (_UIUpdateScheduler.m:1037)
32 UIKitCore 0x000000019307c524 runloopSourceCallback + 92 (_UIUpdateScheduler.m:1186)
33 CoreFoundation 0x0000000190d8d62c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:1957)
34 CoreFoundation 0x0000000190d8c8a8 __CFRunLoopDoSource0 + 176 (CFRunLoop.c:2001)
35 CoreFoundation 0x0000000190d8b058 __CFRunLoopDoSources0 + 244 (CFRunLoop.c:2038)
36 CoreFoundation 0x0000000190d89d88 __CFRunLoopRun + 828 (CFRunLoop.c:2955)
37 CoreFoundation 0x0000000190d89968 CFRunLoopRunSpecific + 608 (CFRunLoop.c:3420)
38 GraphicsServices 0x00000001d507f4e0 GSEventRunModal + 164 (GSEvent.c:2196)
39 UIKitCore 0x00000001931fcedc -[UIApplication _run] + 888 (UIApplication.m:3692)
40 UIKitCore 0x00000001931fc518 UIApplicationMain + 340 (UIApplication.m:5282)
41 SwiftUI 0x0000000195bc3860 closure #1 in KitRendererCommon(_:) + 168 (UIKitApp.swift:51)
42 SwiftUI 0x0000000195bc36a8 runApp<A>(_:) + 152 (UIKitApp.swift:14)
*Last four lines removed due to text length limits.
I've fixed this for myself, I had the GroupID set wrong, oops!
Was set to one for the StoreKit test file in Xcode and not the one in AppStoreConnect
I've resolved this. I realised I could use the console and find the URL call the app makes.
After a bit of reverse engineering I came up with this which works on iOS 16.7.2, 17.4.1 & 17.5
UIApplication.shared.open(URL(string: "App-Prefs:Privacy&path=HEALTH")!, completionHandler: { (success) in
Logger.userevent.info("Settings opened: \(success)")
})
I might possibly have had the same issue as you. I did the following (iOS 17 code) and it solved the issue.
Try putting the "models" inside an
@Observable class <YourModelName>
and then in the view doing
@Bindable var modelBinding = <YourModelName>
ForEach($modelBinding.models) { $value in
ChartView(value: $value)
}
I've had this problem since WatchOS 9 with the move from ClockKit to WidgetKit. I'm not sure if Apple are still interested in .WatchFace files or supporting them properly through WidgetKit....
I think you'll now need to implement the TimelineProvider calls but you can just return a SimpleTimelineProvider entry and ignore the content when creating the SwiftUI view for your app icon.
Have a look at the Apple sample code from the WWDC22 talk Complications and widgets: Reloaded