Adds Widgets.md
This commit is contained in:
parent
58e18f4bcb
commit
a3135da6a8
|
@ -38,7 +38,7 @@
|
|||
176813F52564BB2C00D98635 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 176813F42564BB2C00D98635 /* WidgetKit.framework */; };
|
||||
176813F72564BB2C00D98635 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 176813F62564BB2C00D98635 /* SwiftUI.framework */; };
|
||||
176813FC2564BB2D00D98635 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 176813FB2564BB2D00D98635 /* Assets.xcassets */; };
|
||||
176814002564BB2D00D98635 /* NetNewsWire Widget Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 176813F32564BB2C00D98635 /* NetNewsWire Widget Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
176814002564BB2D00D98635 /* NetNewsWire iOS Widget Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 176813F32564BB2C00D98635 /* NetNewsWire iOS Widget Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
1768140B2564BB8300D98635 /* NetNewsWire_iOSwidgetextension_target.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 1768140A2564BB8300D98635 /* NetNewsWire_iOSwidgetextension_target.xcconfig */; };
|
||||
176814132564BC8A00D98635 /* WidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 176814122564BC8A00D98635 /* WidgetBundle.swift */; };
|
||||
1768142D2564BCA800D98635 /* TimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1768142C2564BCA800D98635 /* TimelineProvider.swift */; };
|
||||
|
@ -1334,7 +1334,7 @@
|
|||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
513C5CF0232571C2003D4054 /* NetNewsWire iOS Share Extension.appex in Embed App Extensions */,
|
||||
176814002564BB2D00D98635 /* NetNewsWire Widget Extension.appex in Embed App Extensions */,
|
||||
176814002564BB2D00D98635 /* NetNewsWire iOS Widget Extension.appex in Embed App Extensions */,
|
||||
5131463E235A7BBE00387FDC /* NetNewsWire iOS Intents Extension.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
|
@ -1490,7 +1490,7 @@
|
|||
176813BD2564BA2800D98635 /* WidgetDataEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataEncoder.swift; sourceTree = "<group>"; };
|
||||
176813C92564BA5400D98635 /* WidgetDataDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataDecoder.swift; sourceTree = "<group>"; };
|
||||
176813D82564BA8700D98635 /* WidgetDeepLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDeepLinks.swift; sourceTree = "<group>"; };
|
||||
176813F32564BB2C00D98635 /* NetNewsWire Widget Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire Widget Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
176813F32564BB2C00D98635 /* NetNewsWire iOS Widget Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire iOS Widget Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
176813F42564BB2C00D98635 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
||||
176813F62564BB2C00D98635 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||
176813FB2564BB2D00D98635 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
|
@ -3340,7 +3340,7 @@
|
|||
51C0513D24A77DF800194D5E /* NetNewsWire.app */,
|
||||
51C0514424A77DF800194D5E /* NetNewsWire.app */,
|
||||
510C415C24E5CDE3008226FD /* NetNewsWire Share Extension.appex */,
|
||||
176813F32564BB2C00D98635 /* NetNewsWire Widget Extension.appex */,
|
||||
176813F32564BB2C00D98635 /* NetNewsWire iOS Widget Extension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3686,9 +3686,9 @@
|
|||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
176813F22564BB2C00D98635 /* NetNewsWire Widget Extension */ = {
|
||||
176813F22564BB2C00D98635 /* NetNewsWire iOS Widget Extension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 176814012564BB2D00D98635 /* Build configuration list for PBXNativeTarget "NetNewsWire Widget Extension" */;
|
||||
buildConfigurationList = 176814012564BB2D00D98635 /* Build configuration list for PBXNativeTarget "NetNewsWire iOS Widget Extension" */;
|
||||
buildPhases = (
|
||||
176813EF2564BB2C00D98635 /* Sources */,
|
||||
176813F02564BB2C00D98635 /* Frameworks */,
|
||||
|
@ -3698,9 +3698,9 @@
|
|||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "NetNewsWire Widget Extension";
|
||||
name = "NetNewsWire iOS Widget Extension";
|
||||
productName = "NetNewsWire WidgetExtension";
|
||||
productReference = 176813F32564BB2C00D98635 /* NetNewsWire Widget Extension.appex */;
|
||||
productReference = 176813F32564BB2C00D98635 /* NetNewsWire iOS Widget Extension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
510C415B24E5CDE3008226FD /* NetNewsWire Share Extension */ = {
|
||||
|
@ -4101,11 +4101,11 @@
|
|||
65ED4090235DEF770081F399 /* Subscribe to Feed MAS */,
|
||||
513C5CE5232571C2003D4054 /* NetNewsWire iOS Share Extension */,
|
||||
51314636235A7BBE00387FDC /* NetNewsWire iOS Intents Extension */,
|
||||
176813F22564BB2C00D98635 /* NetNewsWire iOS Widget Extension */,
|
||||
518B2ED12351B3DD00400001 /* NetNewsWire-iOSTests */,
|
||||
51C0513C24A77DF800194D5E /* Multiplatform iOS */,
|
||||
51C0514324A77DF800194D5E /* Multiplatform macOS */,
|
||||
510C415B24E5CDE3008226FD /* NetNewsWire Share Extension */,
|
||||
176813F22564BB2C00D98635 /* NetNewsWire Widget Extension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
@ -5535,7 +5535,7 @@
|
|||
/* Begin PBXTargetDependency section */
|
||||
176813FF2564BB2D00D98635 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 176813F22564BB2C00D98635 /* NetNewsWire Widget Extension */;
|
||||
target = 176813F22564BB2C00D98635 /* NetNewsWire iOS Widget Extension */;
|
||||
targetProxy = 176813FE2564BB2D00D98635 /* PBXContainerItemProxy */;
|
||||
};
|
||||
510C416824E5CDE3008226FD /* PBXTargetDependency */ = {
|
||||
|
@ -6062,7 +6062,7 @@
|
|||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
176814012564BB2D00D98635 /* Build configuration list for PBXNativeTarget "NetNewsWire Widget Extension" */ = {
|
||||
176814012564BB2D00D98635 /* Build configuration list for PBXNativeTarget "NetNewsWire iOS Widget Extension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
176814022564BB2D00D98635 /* Debug */,
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# Widgets on iOS
|
||||
|
||||
There are _currently_ four widgets available for iOS:
|
||||
|
||||
- 1x small widget that displays the current count of each of the Smart Feeds.
|
||||
- 3x medium widgets—one for each of the smart feeds.
|
||||
|
||||
## Widget Data
|
||||
The widget does not have access to the parent app's database. To surface data to the widget, a small amount of article data is encoded to JSON (see `WidgetDataEncoder`) and saved to the AppGroup container.
|
||||
|
||||
Widget data is written at three points:
|
||||
|
||||
1. After applicationDidFinishLaunching
|
||||
2. As part of a background refresh
|
||||
3. When the scene enters the background
|
||||
|
||||
The widget timeline is refreshed—via `WidgetCenter.shared.reloadAllTimelines()`—after each of the above.
|
||||
|
||||
## Deep Links
|
||||
The medium widgets support deep links for each of the articles that are surfaced.
|
||||
|
||||
If the user taps on an unread article in the unread widget, the widget opens the parent app with a deep link URL (see `WidgetDeepLink`), for example: `nnw://showunread?id={articeID}`. Once the app is opened, `scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>)` is called and is then determined what should be presented to the user. If there is no `id` parameter, the relevant smart feed controller is displayed.
|
||||
|
||||
|
||||
## Data Models
|
||||
```swift
|
||||
struct WidgetData: Codable {
|
||||
|
||||
let currentUnreadCount: Int
|
||||
let currentTodayCount: Int
|
||||
let currentStarredCount: Int
|
||||
let unreadArticles: [LatestArticle]
|
||||
let starredArticles: [LatestArticle]
|
||||
let todayArticles: [LatestArticle]
|
||||
let lastUpdateTime: Date
|
||||
|
||||
}
|
||||
|
||||
struct LatestArticle: Codable, Identifiable {
|
||||
|
||||
var id: String // articleID
|
||||
let feedTitle: String
|
||||
let articleTitle: String?
|
||||
let articleSummary: String?
|
||||
let feedIcon: Data? // Base64 encoded image
|
||||
let pubDate: String
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue