Make it more generic 🌟

This commit is contained in:
Anthony Lasserre 2023-09-12 15:58:20 +02:00
parent 236becbb98
commit 83dac77676
10 changed files with 88 additions and 73 deletions

View File

@ -10,41 +10,56 @@ import SwiftUI
import ActivityKit
struct MyActivityAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var status: String
var driverName: String
var expectedDeliveryTime: String
var data: String
}
}
struct Information: Codable {
let status: String
let driverName: String
let expectedDeliveryTime: String
}
func toJson(dataString: String) -> Information {
let decoder = JSONDecoder()
let stateData = Data(dataString.utf8);
let data = try? decoder.decode(Information.self, from: stateData)
if (data == nil) {
NSLog("Error: %@ %@", "Data is null");
return Information(status: "No status", driverName: "No Driver Name", expectedDeliveryTime: "00:00")
}
return data ?? Information(status: "No status", driverName: "No Driver Name", expectedDeliveryTime: "00:00");
}
@main
@available(iOS 16.1, *)
struct LiveActivityDynamicIsland: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: MyActivityAttributes.self) { context in
HStack {
let data = toJson(dataString: context.state.data)
return HStack {
Image(systemName: "bicycle")
.foregroundColor(.blue)
.padding(8)
VStack(alignment: .leading) {
Text(context.state.status)
Text(data.status)
.font(.body)
Text(context.state.driverName)
Text(data.driverName)
}
Spacer()
VStack(alignment: .trailing) {
Text("Deliver at")
.font(.body)
Text(context.state.expectedDeliveryTime)
Text(data.expectedDeliveryTime)
.font(.footnote)
}
.padding(8)
}
.padding(8)
} dynamicIsland: { context in
DynamicIsland {
let data = toJson(dataString: context.state.data)
return DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
Image(systemName: "bicycle")
.foregroundColor(.blue)
@ -54,24 +69,24 @@ struct LiveActivityDynamicIsland: Widget {
VStack(alignment: .leading) {
Text("Deliver at")
.font(.body)
Text(context.state.expectedDeliveryTime)
Text(data.expectedDeliveryTime)
.font(.footnote)
}
}
DynamicIslandExpandedRegion(.center) {
Text(context.state.status)
Text(data.status)
.font(.body)
}
DynamicIslandExpandedRegion(.bottom) {
Text(context.state.driverName)
Text(data.driverName)
}
} compactLeading: {
Image(systemName: "bicycle")
.foregroundColor(.blue)
} compactTrailing: {
Text(context.state.expectedDeliveryTime)
Text(data.expectedDeliveryTime)
} minimal: {
Text(context.state.expectedDeliveryTime)
Text(data.expectedDeliveryTime)
}
.keylineTint(.yellow)
}

View File

@ -550,6 +550,7 @@
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -616,6 +617,7 @@
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1210"
version = "1.3">
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
@ -22,6 +22,13 @@
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"

View File

@ -573,4 +573,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: a67371d6a35bc642b6ceab68733d885cdd342223
COCOAPODS: 1.11.3
COCOAPODS: 1.12.1

View File

@ -10,10 +10,17 @@ import {
import ActivitiesList from './ActivitiesList';
import Row from './Row';
interface StartLiveActivityParams {
status: string;
driverName: string;
expectedDeliveryTime: string;
}
export default function App() {
const [status, setStatus] = React.useState<string>('Packing');
const [driver, setDriver] = React.useState<string>('John');
const [deliverTime, setDeliveryTime] = React.useState<string>('3pm');
const [driverName, setDriver] = React.useState<string>('John');
const [expectedDeliveryTime, setExpectedDeliveryTime] =
React.useState<string>('3pm');
const [activities, setActivities] = React.useState<any[]>([]);
const [activity, setActivity] = React.useState<any>();
@ -21,23 +28,30 @@ export default function App() {
if (activity) {
setDriver(activity.driverName);
setStatus(activity.status);
setDeliveryTime(activity.expectingDeliveryTime);
setExpectedDeliveryTime(activity.expectingDeliveryTime);
}
}, [activity]);
React.useEffect(() => {
listAllActivities().then(setActivities);
}, [setActivities]);
const onPressCreate = React.useCallback(() => {
startActivity(status, driver, deliverTime).then(() =>
listAllActivities().then(setActivities)
);
}, [status, driver, deliverTime]);
startActivity<StartLiveActivityParams>({
status,
driverName,
expectedDeliveryTime,
}).then(() => listAllActivities().then(setActivities));
}, [status, driverName, expectedDeliveryTime]);
const onPressEdit = React.useCallback(() => {
updateActivity(activity.id, status, driver, deliverTime);
updateActivity<StartLiveActivityParams>(activity.id, {
status,
driverName,
expectedDeliveryTime,
});
setActivity(undefined);
}, [status, driver, deliverTime, activity]);
}, [status, driverName, expectedDeliveryTime, activity]);
const onPressEndActivity = React.useCallback(
(item) => {
@ -63,11 +77,11 @@ export default function App() {
<View style={styles.container}>
<Text style={styles.title}>Live Activities React Native</Text>
<Row onChangeText={setStatus} label="Status" value={status} />
<Row onChangeText={setDriver} label="Driver" value={driver} />
<Row onChangeText={setDriver} label="Driver" value={driverName} />
<Row
onChangeText={setDeliveryTime}
label="Delivery Time"
value={deliverTime}
onChangeText={setExpectedDeliveryTime}
label="Expected Delivery Time"
value={expectedDeliveryTime}
/>
</View>
<Button

View File

@ -1,2 +1,4 @@
#import <React/RCTBridgeModule.h>
#import <React/RCTViewManager.h>
#import <React/RCTConvert.h>
#import <Foundation/Foundation.h>

View File

@ -3,24 +3,10 @@
@interface RCT_EXTERN_MODULE(LiveActivity, NSObject)
RCT_EXTERN_METHOD(startActivity:(NSString)status withDriverName:(NSString)driverName
withExpectingDeliveryTime:(NSString)expectingDeliveryTime
withResolver:(RCTPromiseResolveBlock)resolve
withRejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(listAllActivities:(RCTPromiseResolveBlock)resolve
withRejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(endActivity:(NSString)status withResolver:(RCTPromiseResolveBlock)resolve
withRejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(updateActivity:(NSString)id withStatus:(NSString)status withDriverName:(NSString)driverName
withExpectingDeliveryTime:(NSString)expectingDeliveryTime
withResolver:(RCTPromiseResolveBlock)resolve
withRejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(startActivity:(NSString)data withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(listAllActivities:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(endActivity:(NSString)id withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(updateActivity:(NSString)id withData:(NSString)data withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject)
+ (BOOL)requiresMainQueueSetup
{

View File

@ -4,12 +4,12 @@ import ActivityKit
@objc(LiveActivity)
class LiveActivity: NSObject {
@objc(startActivity:withDriverName:withExpectingDeliveryTime:withResolver:withRejecter:)
func startActivity(status: String, driverName: String, expectingDeliveryTime: String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
@objc(startActivity:withResolver:withRejecter:)
func startActivity(data: String, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void {
if #available(iOS 16.1, *) {
var activity: Activity<MyActivityAttributes>?
let initialContentState = MyActivityAttributes
.ContentState(status: status, driverName: driverName, expectedDeliveryTime: expectingDeliveryTime)
.ContentState(data: data)
let activityAttributes = MyActivityAttributes()
do {
@ -31,7 +31,7 @@ class LiveActivity: NSObject {
var activities = Activity<MyActivityAttributes>.activities
activities.sort { $0.id > $1.id }
return resolve(activities.map{["id": $0.id, "status": $0.contentState.status, "driverName": $0.contentState.driverName, "expectingDeliveryTime": $0.contentState.expectedDeliveryTime ]})
return resolve(activities.map{["id": $0.id, "data": $0.contentState.data ]})
} else {
reject("Not available", "", NSError())
}
@ -48,12 +48,12 @@ class LiveActivity: NSObject {
}
}
@objc(updateActivity:withStatus:withDriverName:withExpectingDeliveryTime:withResolver:withRejecter:)
func updateActivity(id: String, status: String, driverName: String, expectingDeliveryTime: String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
@objc(updateActivity:withData:withResolver:withRejecter:)
func updateActivity(id: String, data: String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
if #available(iOS 16.1, *) {
Task {
let updatedStatus = MyActivityAttributes
.ContentState(status: status, driverName: driverName, expectedDeliveryTime: expectingDeliveryTime)
.ContentState(data: data)
let activities = Activity<MyActivityAttributes>.activities
let activity = activities.filter {$0.id == id}.first
await activity?.update(using: updatedStatus)

View File

@ -11,8 +11,6 @@ import ActivityKit
struct MyActivityAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var status: String
var driverName: String
var expectedDeliveryTime: String
var data: String
}
}

View File

@ -17,12 +17,9 @@ const LiveActivity = NativeModules.LiveActivity
}
);
export function startActivity(
status: string,
driverName: string,
expectingDeliveryTime: string
) {
return LiveActivity.startActivity(status, driverName, expectingDeliveryTime);
export function startActivity<T extends Record<string, any>>(data: T) {
const dataString = JSON.stringify(data);
return LiveActivity.startActivity(dataString);
}
export function listAllActivities() {
@ -33,16 +30,10 @@ export function endActivity(id: string) {
return LiveActivity.endActivity(id);
}
export function updateActivity(
export function updateActivity<T extends Record<string, any>>(
id: string,
status: string,
driverName: string,
expectingDeliveryTime: string
data: T
) {
return LiveActivity.updateActivity(
id,
status,
driverName,
expectingDeliveryTime
);
const dataString = JSON.stringify(data);
return LiveActivity.updateActivity(id, dataString);
}