Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Island interaction & ui not showing #57

Open
Okunamutata opened this issue Nov 10, 2023 · 10 comments
Open

Dynamic Island interaction & ui not showing #57

Okunamutata opened this issue Nov 10, 2023 · 10 comments

Comments

@Okunamutata
Copy link

I've implemented the plugin following the readme. I tried a few times on my project and the counter flutter template project.

After calling _liveActivitiesPlugin.init theres no error. But the return value of that function results to a null.

Im able to call createActivity and receive a String id value.

But nothing is happening visually.

I do see a widget can be added to the homescreen, but thats it.

Heres all the dart code. Any help would be really appreciated

  @override
  void initState() {
    init();
    super.initState();
  }

  @override
  void dispose(){
    _liveActivitiesPlugin.dispose(force: false);
    super.dispose();
  }


  Future<void> init()async{
    try{
      dynamic a  = await _liveActivitiesPlugin.init(
          appGroupId: 'group.<my_bundle_identifier>.sf', urlScheme: 'sf');
      log(a.toString());
    }catch(e){
      log(e.toString());
    }
    activity( widget.workout.exercises.first);
  }
  
  Future<void> activity(ExerciseModel exerciseModel, {int index = 0})async {
    final Map<String, dynamic> activityModel = {
      'name': 'Margherita',
      'ingredient': 'tomato, mozzarella, basil',
      'quantity': 1,
    };
    try{
      if (id == null) {
        id = await _liveActivitiesPlugin.createActivity(activityModel);
        log(id.toString());
      } else {
        await _liveActivitiesPlugin.updateActivity(id!, activityModel);

      }
    }catch(e){
      log(e.toString());
    }
  }
@xTriple
Copy link

xTriple commented Nov 10, 2023

Hi Okunamutata,

I had the same problem, and took me about a day to figure it out, and i have some tips for you:

  1. you don't need to wait for the activity that return
  2. try to move everything related to the liveActivity into the screen file
  3. check your model everything that seems like a special character such as ' , : and so on seems like out of reach, i had an error when i passed into the model '15:10' after i took it out, everything worked fine

  4. check into Xcode that you put Supports Live Activities on true in every info.plist

hope this helps

@Okunamutata
Copy link
Author

Hey @xTriple thanks, i double check the configs and yea its working now. However im unable to read data from UserDefaults(suiteName: on the liveActivity swift file.

Here some of the code, Im able to see my values as createActivty & updateActivity is called. But not sure how to run dynamic island with a debugger ... any way the values default to my String literals

let sharedDefault = UserDefaults(suiteName: "group.<my_bundle_identifier>.sf")!

@available(iOSApplicationExtension 16.1, *)
struct WidgetLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
            // Lock screen/banner UI goes here
            
            let heading = sharedDefault.string(forKey: "name") ?? "Workout in progress"

            let isRest = sharedDefault.bool(forKey: "rest") 
 final Map<String, dynamic> activityModel = <String, dynamic>{
        'name': exerciseModel.mvmt.title,
        'rest': exerciseModel.sets[index].isRest
      };
      try {
        if (id == null) {
          id = await _liveActivitiesPlugin.createActivity(
              activityModel, removeWhenAppIsKilled: true);
          log(id.toString());
        } else {
          await _liveActivitiesPlugin.updateActivity(id!, activityModel);
        }
      } catch (e) {
        log(e.toString());
      }

Any tips would be great 🌮

@xTriple
Copy link

xTriple commented Nov 11, 2023

Hey @Okunamutata, the only way for you to test your Dynamic island with a debugger is only by Xcode. If you think your problem is inside Xcode you can try to create an app iOS native and try from there.
The only tip i can give you about it is:

Try to take the example project swift file
(https://github.com/istornz/flutter_live_activities/blob/main/example/ios/extension-example/extension_example.swift), and set only the bundle id inside the UserDefaults, and then start working from there, i think is pretty easier instead of starting from 0, you should pass the same model
(https://github.com/istornz/flutter_live_activities/blob/main/example/lib/models/football_game_live_activity_model.dart)
and then if it works is just a matter of loosing time creating the dynamic island

let me know how it goes 🧐

@Okunamutata
Copy link
Author

Hey @xTriple thanks. it seems to be an issue with kCFPreferencesAnyUser.

The the dart code init's the plugin this warning is shown in Xcode


Couldn't read values in CFPrefsPlistSource<0x2829e0990> (Domain: group.< my_bundle_identifier >.sf, User: kCFPreferencesAnyUser, ByHost: Yes, Container: (null), Contents Need Refresh: Yes): Using kCFPreferencesAnyUser with a container is only allowed for System Containers, detaching from cfprefsd


@kartikeyaa-k
Copy link

kartikeyaa-k commented Nov 12, 2023

Hi @Okunamutata & @xTriple
I am also facing the exact same issue, I have followed all the steps mentioned. However, nothing is displayed, although console does prints the activity Id, means the activity does get created but nothing on Lock Screen and dynamic island.

configs :
Flutter : 3.13.0
Xcode : 14.1

Update :
The sample app works as expected. I am going to debug and find the issue in my project. Please do provide any findings and I will do the same. Cheers.

@xTriple
Copy link

xTriple commented Nov 12, 2023

Hi @Okunamutata you can follow this thread for the solution (https://developer.apple.com/forums/thread/51348?page=2)
in short if it doesn't crash it can be ignored otherwise try to set the team number, you should have something like 'teamNumber.group.< your_bundle_identifier >.sf'

@kartikeyaa-k for you i can say this:

  1. as for Okuna check your model, quickway is take the sample app and change the model to what you want.
  2. if you wanna pass a string or a date remember to pass it like the example i.e. with DateTime.now().milliseconds and for the image with LiveActivityImageFromAsset('< path to image >')
  3. be sure that the group id shows in white and not red in Xcode
  4. if you print the event in the "liveActivitiesPlugin.activitUpdateStream.listen" if it doesn't show in the console, something like:
    ActiveActivityUpdate(activityId: < activity id >, activityToken: < activity token >
    then there is something wrong dart side or in the Xcode configuration

@kartikeyaa-k
Copy link

kartikeyaa-k commented Nov 12, 2023

Hey @xTriple thanks, i double check the configs and yea its working now. However im unable to read data from UserDefaults(suiteName: on the liveActivity swift file.

Here some of the code, Im able to see my values as createActivty & updateActivity is called. But not sure how to run dynamic island with a debugger ... any way the values default to my String literals

let sharedDefault = UserDefaults(suiteName: "group.<my_bundle_identifier>.sf")!

@available(iOSApplicationExtension 16.1, *)
struct WidgetLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
            // Lock screen/banner UI goes here
            
            let heading = sharedDefault.string(forKey: "name") ?? "Workout in progress"

            let isRest = sharedDefault.bool(forKey: "rest") 
final Map<String, dynamic> activityModel = <String, dynamic>{
       'name': exerciseModel.mvmt.title,
       'rest': exerciseModel.sets[index].isRest
     };
     try {
       if (id == null) {
         id = await _liveActivitiesPlugin.createActivity(
             activityModel, removeWhenAppIsKilled: true);
         log(id.toString());
       } else {
         await _liveActivitiesPlugin.updateActivity(id!, activityModel);
       }
     } catch (e) {
       log(e.toString());
     }

Any tips would be great 🌮

@xTriple I found the issue for my project and it is working now.
@Okunamutata When you are parsing the data on swift side using key, can you try doing it this way :

let isRest: String = sharedDefault.string(forKey: 
            context.attributes.prefixedKey("rest"))!

instead of

let isRest = sharedDefault.bool(forKey: "rest")

and make sure you add the same extension at the bottom from sample file. Verify the name is correct for your project.

Thanks @xTriple

@no-chili
Copy link

Hey @xTriple thanks, i double check the configs and yea its working now. However im unable to read data from UserDefaults(suiteName: on the liveActivity swift file.嘿,谢谢,我仔细检查了配置,是的,它现在可以工作了。但是,我无法从 UserDefaults(suiteName: liveActivity swift 文件上读取数据。

Here some of the code, Im able to see my values as createActivty & updateActivity is called. But not sure how to run dynamic island with a debugger ... any way the values default to my String literals在这里的一些代码中,我能够看到我的值,因为 createActivty & updateActivity 被调用。但不确定如何使用调试器运行动态岛......无论如何,这些值默认为我的 String 文字

let sharedDefault = UserDefaults(suiteName: "group.<my_bundle_identifier>.sf")!

@available(iOSApplicationExtension 16.1, *)
struct WidgetLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
            // Lock screen/banner UI goes here
            
            let heading = sharedDefault.string(forKey: "name") ?? "Workout in progress"

            let isRest = sharedDefault.bool(forKey: "rest") 
 final Map<String, dynamic> activityModel = <String, dynamic>{
        'name': exerciseModel.mvmt.title,
        'rest': exerciseModel.sets[index].isRest
      };
      try {
        if (id == null) {
          id = await _liveActivitiesPlugin.createActivity(
              activityModel, removeWhenAppIsKilled: true);
          log(id.toString());
        } else {
          await _liveActivitiesPlugin.updateActivity(id!, activityModel);
        }
      } catch (e) {
        log(e.toString());
      }

Any tips would be great 🌮任何提示都会很棒 🌮

I added the following code to the swift file to extend the LiveActivitiesAppAttributes and got the value

extension LiveActivitiesAppAttributes {
  func prefixedKey(_ key: String) -> String {
    return "\(id)_\(key)"
  }
}
let emoji: String = sharedDefault.string(forKey:
                        context.attributes.prefixedKey("emoji"))!

@Okunamutata
Copy link
Author

Hey @xTriple thanks, i double check the configs and yea its working now. However im unable to read data from UserDefaults(suiteName: on the liveActivity swift file.嘿,谢谢,我仔细检查了配置,是的,它现在可以工作了。但是,我无法从 UserDefaults(suiteName: liveActivity swift 文件上读取数据。

Here some of the code, Im able to see my values as createActivty & updateActivity is called. But not sure how to run dynamic island with a debugger ... any way the values default to my String literals在这里的一些代码中,我能够看到我的值,因为 createActivty & updateActivity 被调用。但不确定如何使用调试器运行动态岛......无论如何,这些值默认为我的 String 文字

let sharedDefault = UserDefaults(suiteName: "group.<my_bundle_identifier>.sf")!

@available(iOSApplicationExtension 16.1, *)

struct WidgetLiveActivity: Widget {

var body: some WidgetConfiguration {
    ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
        // Lock screen/banner UI goes here
        let heading = sharedDefault.string(forKey: "name") ?? "Workout in progress"
        let isRest = sharedDefault.bool(forKey: "rest") 

final Map<String, dynamic> activityModel = <String, dynamic>{

    'name': exerciseModel.mvmt.title,
    'rest': exerciseModel.sets[index].isRest
  };
  try {
    if (id == null) {
      id = await _liveActivitiesPlugin.createActivity(
          activityModel, removeWhenAppIsKilled: true);
      log(id.toString());
    } else {
      await _liveActivitiesPlugin.updateActivity(id!, activityModel);
    }
  } catch (e) {
    log(e.toString());
  }

Any tips would be great 🌮任何提示都会很棒 🌮

I added the following code to the swift file to extend the LiveActivitiesAppAttributes and got the value


extension LiveActivitiesAppAttributes {

  func prefixedKey(_ key: String) -> String {

    return "\(id)_\(key)"

  }

}


let emoji: String = sharedDefault.string(forKey:

                        context.attributes.prefixedKey("emoji"))!

Thanks. I appreciate the helper function. It works now.

@adham-ashraf77
Copy link

  • be sure that the group id shows in white and not red in Xcode

I have the same issue how you solve it please @Okunamutata

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants