macOS installer
Are there plans for macOS support?
I plan to support it eventually, but at the moment I do not have access to any apple devices so I can't work on it. If anyone with a mac is willing to help out PRs are welcome :D
I recommend mentioning it in the README and in the release notes. Something like this:
macOS support
macOS and iOS support is planned, however I don't have access to any Apple device. Pull requests or Apple devices are welcome.
Quick note that I've just started trying out commet (as a web app) on both iOS (iPhone) and macOS (MacBook laptop), so I'm going to start looking at whether I can build or run commet as an app on both of those platforms, and I'm happy to use my devices for testing out builds and/or fixes.
Unfortunately I'm 99.9% a python developer (the remaining 0.01% is split between IDL and FORTRAN, because I'm an astronomer), so I'm probably not best able to actually fix code without a substantial learning curve, but that said I'm willing to start working on that as I can.
Quick note that I've just started trying out commet (as a web app) on both iOS (iPhone) and macOS (MacBook laptop), so I'm going to start looking at whether I can build or run commet as an app on both of those platforms, and I'm happy to use my devices for testing out builds and/or fixes.
Unfortunately I'm 99.9% a python developer (the remaining 0.01% is split between IDL and FORTRAN, because I'm an astronomer), so I'm probably not best able to actually fix code without a substantial learning curve, but that said I'm willing to start working on that as I can.
that would be amazing! I'm of course happy to provide any assistance with understanding the codebase
A question and a slightly expanded note. For the question, is there a preferred IDE or tool set that you use for development?
For the note, my rough plan on this is that the macOS app will need to start work first, followed by anything iOS. My reasoning on that is
- To build a mac app in the first place is fairly straightforward, and if you built it locally you can run it locally.
- Mac apps become a bit more difficult when you want other testers, because in order to avoid massive issues in trying to actually install the thing, I (or whoever) will have to get an active apple developer certificate (easy enough, I just have to renew it), and get the app signed and notarized after build (for Mac apps, this is automated and easy)
- iOS apps (other than in the EU, and there are additional issues there) need to go through the App Store, and I have no idea if this app would actually be allowed. For testing, personal testing is easy, and small community testing for an unreleased app via TestFlight is decently easy, but it's an additional set of stuff that you don't have to worry about locally.
A question and a slightly expanded note. For the question, is there a preferred IDE or tool set that you use for development?
I just use vscode, and whatever version of flutter is currently listed on the README
Mac apps become a bit more difficult when you want other testers, because in order to avoid massive issues in trying to actually install the thing, I (or whoever) will have to get an active apple developer certificate (easy enough, I just have to renew it), and get the app signed and notarized after build (for Mac apps, this is automated and easy)
I'll manage signing, does this process need an apple device also?
iOS apps (other than in the EU, and there are additional issues there) need to go through the App Store, and I have no idea if this app would actually be allowed. For testing, personal testing is easy, and small community testing for an unreleased app via TestFlight is decently easy, but it's an additional set of stuff that you don't have to worry about locally.
Realistically, we are aiming to get an app store release eventually. If there are certain things which are not allowed on app store, we will just have to disable them for apple platforms as we dont really have any other option. I think a proper release is some ways away, but I'd be open to getting started with TestFlight stuff soon maybe
Okay, I had a walk through flutter and dart versions, and a little side trip into trying to make a linux VM and develop there, only to discover that a bunch of the required modules are not available for linux on ARM. As a reference so far, on the macOS development side, we have the following:
- commet is built on Flutter 3.22.3, but on macOS Flutter 3.22.3 isn't compatible with dart > 3.44.0, and commet requires dart 3.5. The lowest version of Flutter that supports dart 3.5 is 3.24.0, so I've been using that.
- commet uses a form of web authentication that requires that macOS build target to be >= 10.15 (rather than 10.14).
- There's a weird bug where cocoapods creates a build target that doesn't exist and then fails to find it, but there's also a workaround for that. I'm hoping to figure out why, but for now I'll take figuring out how
- In order to actually connect to servers, commet needs to request the network.client entitlement
With the above changes, I'm able to build a Mac version of commet. Because libolm is deprecated, getting it to install automatically doesn't seem to be working, but I can install it myself after building, which isn't ideal but which works. Will report more when I have more to report.
I now have an iOS version in TestFlight to let me see how it goes
As a reference, as best I can tell to do the actual code signing, you do need to be running on a macOS system with XCode. That said, I know that GitHub actions has Mac systems (or virtual machines, or whatever) available, and I know that there exist ways of doing code signing using GitHub, and the Flutter documentation talks about ways of handling both code signing and uploading to the App Store via the command line (so again it could be done as part of a GitHub action workflow). I know that setting up signing certificates, app identifiers, test flight builds, and App Store submission can all be done via the apple developer website
commet is built on Flutter 3.22.3, but on macOS Flutter 3.22.3 isn't compatible with dart > 3.44.0, and commet requires dart 3.5. The lowest version of Flutter that supports dart 3.5 is 3.24.0, so I've been using that.
We are currently on 3.24.4, so that should be fine
As a reference, as best I can tell to do the actual code signing, you do need to be running on a macOS system with XCode. That said, I know that GitHub actions has Mac systems (or virtual machines, or whatever) available
I'd be keen to get some actions going, if that's something you would be interested in working on?
My current set of priorities here is (roughly)
- Finish up the PR for the keyboard adapter
- File a PR that gets the macOS and iOS versions building successfully
- Spin up notifications in iOS (as I understand it so far, iOS push notifications in flutter apps use Firebase to talk with the Apple Push Notification (APN) server, so in theory this is mostly a matter of making sure that the app has the correct entitlements (push notifications, background fetch, and remote notifications) and then doing testing on an actual device (you can't test notifications on the simulator because APN, by design, can only send notifications to an actual hardware device).
- Same but MacOS (I think it's supposed to work the same way as iOS, except that on a desktop you don't need an entitlement for background processing, just for connecting to APN)
I'm happy to look at getting signing set up as a GitHub workflow thereafter (also because that seems like kind of the minimum viable product for anyone other than me to try to run). For the moment I can set up the actions to securely import and use my credentials for signing and uploading, and once you have credentials set up, if you wish to, we can switch to yours. For the moment I'm working on it with an app identifier of chat.commet.commetapp.quirt, just to make sure I'm not stepping on the app ID that you'd want to use to officially distribute to the app store, and I'm not planning on taking the app out of beta and submitting it without an explicit go on your part.
Just as a note, I think I'm ready to add push notification support to my iOS test platform. The one remaining thing that I have to do is to upload the Apple push key to commet's Firebase project, which means either I need to be able to do that, or I need a secure way of sending the key to you so that you can do that. See https://firebase.flutter.dev/docs/messaging/apple-integration/ for the checklist I'm currently working through. I've finished all of the steps except for adding the key to the Firebase console (and I'm not touching putting images in notifications yet).
As far as anything relating to backend / APNs / firebase, I wont really be comfortable adding keys from anything that isnt 100% managed by me. if you are wanting to do any tests like this, you are going to have to set up your own firebase project and configure it there.
I'm happy to work with you to get this set up, but it will have to be managed by me.
Also, due to US Cryptographic Export regulations, it may not be wise to make your beta accessible to the public, nor to use it to download to your own device if you are outside of the US, as it may not be legal. I can't give any legal advice on this, but its something you need to be aware of.
That makes sense. From the code it had looked like you were already using Firebase, so I didn't want to step on that. If you don't mind me setting up my own firebase for iOS testing, I'll do that, and I'll give you the information so that, once you have your own keys set up, and want to distribute, there hopefully won't be any surprises.
I am in fact in the US (I'm Canadian but a permanent US resident) so I'm at least in okay shape from that end.
So yes, let me know if you're okay with my setting up firebase on my end for the purpose of testing. I'm not planning on making the beta publicly available, and I'm not planning on releasing it, my hope is to get things to the point where there won't be any surprises on your end.
So, I should ask specifically, are you okay with my setting up a Firebaase project to test this, with the above caveat that I'll file pull requests for anything that needs to be done to enable the setup, and I'll share what I needed to do to get it working. And, of course, I'm not planning on taking my version of this out of beta/testflight, or on making even the TestFlight available to the public. And once you've gotten your developer credentials set up for delivering your own builds, I'll take down my projects.
If it's just something for you to test with during development, and it is understood that anything connecting commet to your firebase or any other accounts and services that you have created will have to be removed before anything can be merged, then I don't see any reason it should be a problem to me.
And of course, as per the license of the project, you can do whatever you wish.
I do again want to stress the importance of making sure you are complying with regulations in regard to cryptography here whenever builds are being uploaded to new services. It may be wise to disable/remove E2EE while working on this, if you want to be safe. Commet should be able to launch and run smoothly even with libolm missing, of course with encrypted rooms no longer functioning properly
Thank you. And agreed WRT cryptography. This is why I'm specifically doing distribution as a private TestFlight (as in, instead of there being a public link to sign up, I can add specific people, and they're allowed to test on their devices, but that's it). This way, I can restrict testing to people I know personally, which means I also know where they live.
In order to make the app available in the App Store at all, you need to fill in statements about what encryption you use (actually, you need to do that even to put a beta version on your own phone through TestFlight, as opposed to running it by connecting your phone to your computer to do connected testing). I know that Element and FluffyChat both support encryption, and are both available on the App Store, which means that one of the following is true:
- libolm uses standardized encryption, and thus the only paperwork you need to file is you need to file a specific form for the French government if you're making it available in France
- libolm is not standardized encryption, but when you fill in the US export control paperwork, Apple gets and passes on an OK to distribute on the store
- Every existing iOS matrix client that supports encryption is just lying to apple, and none of them have been caught.
I'm assuming neither of us is planning on doing that last one, so my thought is when you're at the point where you're thinking of making it live on the App Store, if there are any problems, then the matrix community actually seems decently friendly, so they might well be willing to help with how they did it.
The existing PR for Mac/iOS does have push notifications (and "receive background notifications" turned on in the app's requested capabilities, but that's something that would be needed to support notification whoever is distributing it, and it's not something that would be different in terms of what I set up. The necessary code changes to support push notifications (which amount to defining a notification class to return for iOS and macOS) are things that I would like to merge, because they, again, wouldn't be different either. Any code that defines a specific FireBase backend is something I would not merge.
Is that something that would work for you? It would mean that, essentially, if you merged my PR into the main repository (by which I mean a future PR, not the current compatibility PR), commet for iOS (and eventually macOS) would be set up to use firebase notifications, but there would be nothing specific to my set-up in the repository. It might take a bit of time to get the correct balance, because it can be hard to know, exactly, what is being set where, especially with the somewhat opaque XML files that are all through Xcode build set-ups, but that would be the goal.
In terms of notifications for iOS, I'm at the point where push notifications work, but only when the app is open. I have an idea of what might be going on here, but I'm failing to figure out the relevant part of the code. What I'm looking for is, ultimately, the code that turns a notification into a JSON object, or that controls the push notification that Firebase would get when something happens in matrix that commet would send a notification for. I think there's a specific parameter that, if missing, will cause apple push to only deliver the notification the next time the app is opened, but I can't figure out where to look to check.
Ultimately, I think what's going on here is related to the way that push.commet.chat formats its notifications. I have established that sending a notification for commet iOS directly through the Firebase console works as expected (it appears whether commet is foreground or background), but notifications sent round-trip through commet (i.e. by sending a message from one person on a matrix homeserver, using commet, only shows the notification when commet is next opened.
From research online, and looking at logs, it seems like the difference is that notifications sent through the console include, in their JSON, an "apns" dictionary and a "content_available" key. Doing further research into other iOS commet clients that are able to receive notifications, in particular the Element client, which seems to use the sygnal push server, the Pusher set up through that uses the "default_payload" dictionary which sets values for "aps" "mutable-content", and "content_available"). FluffyChat appears to set a "data_message": "ios" key/value, which appears to translate into setting the necessary keys.
There is a lot of disagreement online about what, exactly, the JSON should look like, but https://stackoverflow.com/questions/77164628/ios-background-handler-not-getting-invoked-for-firebase-push-notifications-in-re seems to hold something fairly close to the consensus, such as it is, although in general it appears that both the "content_available" and "apns" values need to be set. I'm happy to discuss this more if it would be helpful.