omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    [Share code] ReminderStore - not what Apple intended

    Pythonista
    5
    10
    5368
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • mikael
      mikael last edited by mikael

      Logo

      Link to Github

      From the readme:

      ReminderStore

      Key-value store using iOS Reminders for persistence and distribution across iOS devices.

      Introduction

      ReminderStore is a Pythonista persistence provider. It uses the reminders module to store the values in a specific list in the iOS Reminders app. If you set that list to be distributed across your iOS devices, you get a free cloud-based storage for your app data, suitable for prototyping different distributed use cases.

      API

      Create a store object providing the name of the Reminders list to be created/used:

      store = ReminderStore(namespace, to_json=False, cache=False)

      Use the store object to store, retrieve, list and delete items:

      • Store: store['key'] = 'value'
      • Retrieve: store['key']
      • List: for key in store: print store[key]
      • Delete: del store['key']

      If you want to store structures instead of plain strings, set to_json=True. Store and retrieval operations will then serialize and restore the values to and from JSON.

      Setting cache=True reduces direct access to the Reminders app. Use the refresh_cache() method to refresh the cache and get information on any background changes. See Notes below for more details.

      Notes

      • Key is stored as the title of the reminder, and value in the notes field.
      • Reminder titles are not unique, but ReminderStore uses an intermediate dict to enforce uniqueness. Results are likely to be unproductive if you create duplicate titles manually.
      • Key is used as-is if it is a plain or unicode string. Otherwise str() is called on key before using it.
      • By default, ReminderStore goes to the Reminders app to get the latest information. This is somewhat inefficient since checking for new items always requires loading the full list. There are two cases where you might to prefer to activate the intermediate caching instead:
        • If you have no-one making any updates remotely, cache will be more efficient and will never need manual refreshing.
        • If you want to get more control over when any background changes are applied in your app, use the caching and call refresh_cache to check and process changes. The method returns None if there are no changes, or a dict with added, deleted and changed sets if there are changes. Each set contains the keys of the stored items that were inserted, deleted or had their contents modified, respectively. You can use this info to e.g. remove deleted items from the UI, or inform the user of a conflict and let them decide which version to keep.
      • Note that iOS Reminders app provides no support for complex atomic transactions or referential integrity between items.
      1 Reply Last reply Reply Quote 5
      • ywangd
        ywangd last edited by

        This is a quite creative idea. I wonder if it can be extended to provide an alternative solution to sync user scripts across devices. A few existing tools use Dropbox or webdav servers. But iCloud would definitely be an attractive option.

        My guess is that one could use both RemiderStore and pyzipista by @marcus67 to achieve the sync. Basically pyzipista provides serialisation of files and folders and RemiderStore provides data transport and communication. Some design is likely needed to take care how data and their metadata are stored in the reminder. Is there a character limit of the notes field? I tried with over 60K and it worked fine.

        1 Reply Last reply Reply Quote 1
        • mikael
          mikael last edited by

          Thought about it, and concluded that it is certainly possible, but probably a bad idea for larger amounts of larger files.

          I do not know and have not had time to test what kind of a size limit there is on the notes section of a reminder, and whether it gives any error or just cuts the extra if such a limit is reached.

          Also, the reminders module is such that there is no way to list reminders and just load one - it behaves like it loads the whole list at once. This can be cumbersome if there are several large files, all in memory at the same time.

          Hmm, have to take a closer look at the module implementation.

          1 Reply Last reply Reply Quote 1
          • ccc
            ccc last edited by

            You can share reminder lists with others... This might be a cool technique for free device-to-device comms in a multiplayer game with delayed delivery when a player is not online.

            1 Reply Last reply Reply Quote 1
            • mikael
              mikael last edited by

              Yes. Cool idea. Messages would need to be encrypted, though, otherwise opening the Reminders app and tampering with results might be too tempting...

              My Pythonista-fu is weak. I cannot find the code for the reminders module.

              1 Reply Last reply Reply Quote 1
              • ccc
                ccc last edited by

                import inspect, reminders
                print(inspect.getsource(reminders))
                

                is the usual approach viewing the source of a module but it fails because reminders is a builtin module so no source is provided.

                Encryption could be done via https://github.com/dlitz/pycrypto which is provided in Pythonista.

                1 Reply Last reply Reply Quote 1
                • mikael
                  mikael last edited by

                  @omz: When you are not busy otherwise, could you please share/check whether the reminders implementation is such that when getting all the reminders for a list, it only creates proxy objects to the Reminders app, or whether it creates instantiated objects, i.e. reading all the data into Pythonista?

                  1 Reply Last reply Reply Quote 1
                  • dgelessus
                    dgelessus last edited by

                    @mikael It looks very much like Reminder, Calendar, etc. are just proxies. All of their attributes are really getset_descriptors (though that is the standard for most C classes, not just proxies) and gc.get_referents shows no Python objects being referred to (though there might still be C data).

                    1 Reply Last reply Reply Quote 1
                    • mikael
                      mikael last edited by

                      @dgelessus, thanks. If that is true, creating a iCloud-based file sync between devices would seem feasible. I could take it on once my current project is done.

                      1 Reply Last reply Reply Quote 0
                      • omz
                        omz last edited by

                        @mikael The Reminder class is essentially just a wrapper for the Objective-C class EKReminder (from the EventKit framework). How and when exactly the data for each reminder is fetched from the database is basically an implementation detail, and it's hard to tell without having access to the source code.

                        1 Reply Last reply Reply Quote 2
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors