ios live activity
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
6
filcnaplo/ios/livecard/Assets.xcassets/Contents.json
Normal file
6
filcnaplo/ios/livecard/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
11
filcnaplo/ios/livecard/Info.plist
Normal file
11
filcnaplo/ios/livecard/Info.plist
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.widgetkit-extension</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
27
filcnaplo/ios/livecard/lesson_model.swift
Normal file
27
filcnaplo/ios/livecard/lesson_model.swift
Normal file
@@ -0,0 +1,27 @@
|
||||
import Foundation
|
||||
|
||||
class LessonData {
|
||||
var icon: String
|
||||
var index: String
|
||||
var title: String
|
||||
var subtitle: String
|
||||
var description: String
|
||||
var startDate: Date
|
||||
var endDate: Date
|
||||
var date: ClosedRange<Date>
|
||||
var nextSubject: String
|
||||
var nextRoom: String
|
||||
|
||||
init?(JSONData data:[String: String]) {
|
||||
self.icon = data["icon"]!
|
||||
self.index = data["index"]!
|
||||
self.title = data["title"]!
|
||||
self.subtitle = data["subtitle"]!
|
||||
self.description = data["description"]!
|
||||
self.startDate = Date(timeIntervalSince1970: Double(data["startDate"]!)! / 1000)
|
||||
self.endDate = Date(timeIntervalSince1970: Double(data["endDate"]!)! / 1000)
|
||||
date = self.startDate...self.endDate
|
||||
self.nextSubject = data["nextSubject"]!
|
||||
self.nextRoom = data["nextRoom"]!
|
||||
}
|
||||
}
|
||||
59
filcnaplo/ios/livecard/livecard.intentdefinition
Normal file
59
filcnaplo/ios/livecard/livecard.intentdefinition
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>INEnums</key>
|
||||
<array/>
|
||||
<key>INIntentDefinitionModelVersion</key>
|
||||
<string>1.2</string>
|
||||
<key>INIntentDefinitionNamespace</key>
|
||||
<string>88xZPY</string>
|
||||
<key>INIntentDefinitionSystemVersion</key>
|
||||
<string>20A294</string>
|
||||
<key>INIntentDefinitionToolsBuildVersion</key>
|
||||
<string>12A6144</string>
|
||||
<key>INIntentDefinitionToolsVersion</key>
|
||||
<string>12.0</string>
|
||||
<key>INIntents</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentCategory</key>
|
||||
<string>information</string>
|
||||
<key>INIntentDescriptionID</key>
|
||||
<string>tVvJ9c</string>
|
||||
<key>INIntentEligibleForWidgets</key>
|
||||
<true/>
|
||||
<key>INIntentIneligibleForSuggestions</key>
|
||||
<true/>
|
||||
<key>INIntentName</key>
|
||||
<string>Configuration</string>
|
||||
<key>INIntentResponse</key>
|
||||
<dict>
|
||||
<key>INIntentResponseCodes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentResponseCodeName</key>
|
||||
<string>success</string>
|
||||
<key>INIntentResponseCodeSuccess</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentResponseCodeName</key>
|
||||
<string>failure</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>INIntentTitle</key>
|
||||
<string>Configuration</string>
|
||||
<key>INIntentTitleID</key>
|
||||
<string>gpCwrM</string>
|
||||
<key>INIntentType</key>
|
||||
<string>Custom</string>
|
||||
<key>INIntentVerb</key>
|
||||
<string>View</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INTypes</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
137
filcnaplo/ios/livecard/livecard.swift
Normal file
137
filcnaplo/ios/livecard/livecard.swift
Normal file
@@ -0,0 +1,137 @@
|
||||
import ActivityKit
|
||||
import WidgetKit
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct Widgets: WidgetBundle {
|
||||
var body: some Widget {
|
||||
if #available(iOS 16.1, *) {
|
||||
LiveCardWidget()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We need to redefined live activities pipe
|
||||
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
|
||||
public typealias LiveDeliveryData = ContentState
|
||||
|
||||
public struct ContentState: Codable, Hashable {
|
||||
var data: Dictionary<String, String>
|
||||
}
|
||||
|
||||
var id = UUID()
|
||||
}
|
||||
|
||||
@available(iOSApplicationExtension 16.1, *)
|
||||
struct LiveCardWidget: Widget {
|
||||
var body: some WidgetConfiguration {
|
||||
/// Live Activity Notification
|
||||
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
|
||||
let lesson = LessonData(JSONData: context.state.data)
|
||||
|
||||
HStack(alignment: .center) {
|
||||
Image(systemName: lesson!.icon)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: CGFloat(30), height: CGFloat(30))
|
||||
.padding(.leading, CGFloat(8))
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text(lesson!.index + lesson!.title)
|
||||
.font(.title3)
|
||||
.bold()
|
||||
|
||||
Text(lesson!.description)
|
||||
.font(.subheadline)
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack {
|
||||
Image(systemName: "arrow.right")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: CGFloat(12), height: CGFloat(12))
|
||||
Text(lesson!.nextSubject)
|
||||
.font(.caption)
|
||||
Text(lesson!.nextRoom)
|
||||
.font(.caption2)
|
||||
}
|
||||
}.padding(15)
|
||||
|
||||
Spacer()
|
||||
|
||||
Text(lesson!.subtitle)
|
||||
.font(.subheadline)
|
||||
.padding(.trailing, 12)
|
||||
}.padding(12)
|
||||
/// Dynamic Island
|
||||
} dynamicIsland: { context in
|
||||
let lesson = LessonData(JSONData: context.state.data)
|
||||
|
||||
/// Expanded
|
||||
return DynamicIsland {
|
||||
DynamicIslandExpandedRegion(.leading) {
|
||||
VStack {
|
||||
Spacer()
|
||||
Image(systemName: lesson!.icon)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: CGFloat(30), height: CGFloat(30))
|
||||
.padding(.leading, CGFloat(6))
|
||||
.padding(.bottom, CGFloat(6))
|
||||
}
|
||||
}
|
||||
DynamicIslandExpandedRegion(.center) {
|
||||
VStack(alignment: .leading) {
|
||||
Text(lesson!.index + lesson!.title)
|
||||
.lineLimit(1)
|
||||
.font(.title3)
|
||||
.bold()
|
||||
|
||||
Text(lesson!.description)
|
||||
.lineLimit(2)
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
DynamicIslandExpandedRegion(.trailing) {
|
||||
VStack {
|
||||
Spacer()
|
||||
Text(lesson!.subtitle)
|
||||
.lineLimit(1)
|
||||
.font(.subheadline)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
||||
/// Compact
|
||||
} compactLeading: {
|
||||
Label {
|
||||
Text(lesson!.title)
|
||||
} icon: {
|
||||
Image(systemName: lesson!.icon)
|
||||
}
|
||||
.font(.caption2)
|
||||
} compactTrailing: {
|
||||
Text(timerInterval: lesson!.date, countsDown: true)
|
||||
.multilineTextAlignment(.center)
|
||||
.frame(width: 40)
|
||||
.font(.caption2)
|
||||
|
||||
/// Collapsed
|
||||
} minimal: {
|
||||
VStack(alignment: .center) {
|
||||
Image(systemName: lesson!.icon)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: CGFloat(12), height: CGFloat(12))
|
||||
|
||||
Text(timerInterval: lesson!.date, countsDown: true)
|
||||
.multilineTextAlignment(.center)
|
||||
.monospacedDigit()
|
||||
.font(.system(size: CGFloat(10)))
|
||||
}
|
||||
}
|
||||
.keylineTint(.accentColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user