Closed romainchkr closed 8 months ago
I've been having issues with the module code being used, expo changed somewhere between updates and it broke. To check, remove your module file (put it elsewhere as a backup) and try passing the correct model directly from javascript.
I've been having issues with the module code being used, expo changed somewhere between updates and it broke. To check, remove your module file (put it elsewhere as a backup) and try passing the correct model directly from javascript.
You are right I didn't notice but passing data from react native to the swift widget is not working anymore.
What do you mean by
removing the module file and try passing the correct model directly from javascript
For the moment i'm passing data from RN to Swift using the code inside the module file (i i understand good) and calling the following in RN :
import * as ExpoWidgetsModule from '@bittingz/expo-widgets';
ExpoWidgetsModule.setWidgetData({groupName: 'disconnected', backgroundImage: '', messages: [], type: 'disconnected'});
I don't see how I should do without the module file.
Even tho I tried to delete the Module.swift and launched the app but it doesn't seems to work. The data is still not passing from RN to the IOS widget.
Do you have a workaround ?
The library used to allow you to provide a module file but expo changed something and it stopped working.
Instead, it just uses the libraries module file. So if you look at the example project, it just sends an object from js that has the same format as the swift object. It's swapped over by json. Make sure your key is correct if you don't get any data. If you can pass a simple object of one field correctly but it doesn't work for nested then I'll investigate. For my project I only have no nesting in my object so tbh I haven't considered this yet. But I have many properties passed.
One key point is making sure the json for messages works. If you have certain renames between your react native JavaScript and the swift widget, either change them to match or map them before sending over.
Okay i will try with a simple object then.
If I understand good what I should do is the following:
var data = { groupName: 'my group', backgroundImage: 'https://....'};
ExpoWidgetsModule.setWidgetData(JSON.stringify(data));
having the following MyData structure in swift :
public struct MyData: Codable {
var groupName: String
var backgroundImage: String
}
It seems impossible to compile the app without any Module.swift file in the widgets/ios folder.
I finally managed.
Here is how i did for anyone interested :
// MyData.swift
public struct MyMessage: Codable {
var name: String
var message: String
var isMe: Bool
}
public struct MyData: Codable {
var groupName: String
var backgroundImage: String
var messages: [MyMessage]
var type: String
var nbFire: Int
}
// Module.swift
import ExpoModulesCore
import ActivityKit
import WidgetKit
public class ExpoWidgetsModule: Module {
public func definition() -> ModuleDefinition {
Name("ExpoWidgets")
Function("setWidgetData") { (data: String) -> Void in
let logger = Logger()
do {
logger.info("!! setWidgetData");
let widgetSuite = UserDefaults(suiteName: "group.com.myapp.expowidgets")
widgetSuite?.set(data, forKey: "MyData")
logger.info("!! Encoded data saved to key MyData")
if #available(iOS 14.0, *) {
WidgetCenter.shared.reloadAllTimelines()
}
}
catch (let error) {
logger.info("An error occured setting MyData!")
}
}
}
}
// Entries
struct Entry: TimelineEntry {
var date: Date = .now
var groupName: String = ""
var backgroundImage: String = ""
var messages: [Message] = []
var type: String = "disconnected"
var nbFire: Int = 0
var image: Loadable<Image>
}
struct Message: Identifiable {
var id = UUID()
var name: String
var message: String
var isMe: Bool
}
// How i retrieve the data from the userdefault
let widgetSuite = UserDefaults(suiteName: "group.com.rocketapp.privatewidget2.expowidgets")
if let jsonData = widgetSuite?.string(forKey: "MyData") {
do {
if let data = jsonData.data(using: .utf8) {
let widgetData = try JSONDecoder().decode(MyData.self, from: data)
let entry = Entry(
date: Date(),
groupName: widgetData.groupName,
backgroundImage: widgetData.backgroundImage,
messages: widgetData.messages.map { Message(name: $0.name, message: $0.message, isMe: $0.isMe) },
type: widgetData.type,
nbFire: widgetData.nbFire,
image: Loadable<Image>.notRequested
)
return entry
} else {
...
}
} catch {
...
}
}
Hello,
First thank you for that amazing package. it works great. Right now i'm trying to pass nested object data from react to the widget (ios only) but its seems quite challenging.
I started from your example wich works great and I tried to add a list of Message object to the myData struct.
I have the following MyData.swift :
The following Module.swift :
And i decode it like that in swift :
With this code i face the following issue :
I'm not really familiar to swift and I tried different things but I face all the time issues. I'm wondering if you have any clue ?
Thank you.