Flutter application development: feedback (2/2)
Application development in Flutter: Publishing to application stores (2/2)
Publishing a video streaming application from the Fediverse on various application stores was like navigating an obstacle course.
Due to the stores' sometimes very strict policies and the sensitivity surrounding video content — particularly that generated or broadcast by third parties — we had to exercise extreme caution. Apple and Google consider us, as the application's publisher, responsible for all content accessed via the application. They are particularly strict on this issue with regard to video formats, much more so than with podcast applications or web browsers.
Here's an overview of the various stages, from the initial submission to the production launch.
Precautions taken
To maximise our chances of being accepted by the stores, we took several precautions right from the start.
Filtering accessible platforms
The first measure was to restrict access to the platforms via a filtering system using identifiers specific to each store. This identifier is used to maintain an allowlist of trusted platforms adapted to each store.
- On the Play Store (Android), only a restricted allowlist of platforms is accessible to meet Google's requirements.
- On the App Store (iOS), the allowlist is even more limited, with Apple imposing particularly stringent validation criteria.
- On F-Droid, however, all platforms listed in our moderated index are accessible without additional filtering.
The advantage of this tag-based system is that it is entirely deported server-side. In other words, if we need to remove a problematic platform or add a new one, this can be done without updating the application itself. This gives us great flexibility and responsiveness when the need arises.
No manual addition of platforms at the start
To ensure the first submission was validated quickly, we deliberately disabled the option to manually add a platform in the application. Consequently, only the platforms authorized by our filter, of which there were very few, were available.
Once the application had been validated and was available on the Play Store, we re-enabled manual addition of platforms on the Android side, watching carefully to see if it caused any problems. After several months with no negative feedback, we opened this possibility on iOS as well.
Presentation and deployment strategy
To give ourselves the best possible chance of success, we paid particular attention to the user interface and the store listings (thumbnails, descriptions, keywords, screenshots, etc.). This is because the stores also pay close attention to appearance, perceived quality, and adherence to good UX/UI practices.
We decided to take a step-by-step approach:
- First the Play Store, which is faster and more flexible.
- Then the App Store, which is more demanding but unavoidable.
- Finally, F-Droid, which requires a different approach and is essential for FOSS users.
Google Play Store: smooth validation
The official Flutter documentation was followed for publication on the Google Play Store:
https://docs.flutter.dev/deployment/android.
The Play Store allows several deployment types, which are useful for testing different stages of the application:
- Internal testing: This allows you to distribute the app to a small group of internal testers (up to 100).
- Closed testing: Allows you to target a larger select group via an email address list or Google group.
- Open testing: Allows any user to join the testing programme via a public link.
- Production: This is the stable version published on the Play Store for all users.
Validation steps
Each deployment type is automatically validated by Google with very short turnaround times.
- Internal and closed tests are generally available within an hour.
- Open tests and production releases can take a few hours, but rarely more.
Google has always accepted the application upon initial submission, without requesting changes or asking questions. There have been no exchanges or feedback from them, just validation after submission and a well-written changelog.
It seems that the precautions we took beforehand were sufficient, or even that we could have been more relaxed!
Apple App Store: complications...
Once I had successfully navigated the Google process, it was time to move on to Apple, which is known for being significantly more demanding.
As with Android, I followed the official Flutter documentation for iOS deployment.
[Flutter iOS Deployment] (https://docs.flutter.dev/deployment/ios).
On iOS, apps can be distributed through two main channels:
- TestFlight: for sharing beta versions with up to 10,000 testers. This process is more flexible than the production process, but is still subject to validation.
- Production: the stable, public version of the app, visible on the App Store.
The validation steps
Gabe's warning
Before submitting PeerTube to iOS, we consulted Gabe, the developer behind the OwnCast project, who had previously been rejected several times by Apple. He shared his valuable feedback and strategies for complying with the App Store Guidelines. Here is a summary:
-
Guideline 1.2 – Security – User-generated content
➤ Solution: Integrate a client-side “reporting” system that sends an email to a moderator who can remove an instance if necessary. -
Guideline 5.2.3 – Legal aspects
Your app contains content or features that may violate the rights of one or more third parties. Specifically, your app provides potentially unauthorized access to third-party audio or video streaming, catalogs, and discovery services.
➤ Solution: Provide a PDF document listing each video server preconfigured in the app, with “Authorized” marked for each one. Apple is not satisfied with a simple statement: they want tangible proof.
-
Guideline 3.1.1 – Commercial Activity – Payments – In-App Purchases
➤ Problem: The app allowed donations via links such as PayPal, OpenCollective, KoFi, etc.
➤ Solution: Remove all payment-related interactions from the app. All links to donations must open a page in an external browser (Safari, Chrome, etc.). No payment links should be displayed in an internal WebView. -
Guideline 5.2.3 – Legal (bis)
➤ Solution: Provide as much documentation, links, and evidence as possible that the integrated catalogs and discovery services are operated by us and not by an unauthorized third party.
Thanks again to Gabe for his valuable advice!
We got started and hit a snag.
Despite rigorously following Gabe's advice, Apple didn't cut us any slack.
Of the two apps we were trying to publish at the end of 2024 — Lokas and PeerTube — we received eight rejections for Lokas before getting approval and three for PeerTube.
As soon as an Apple reviewer found an issue, even a minor one, the request was rejected and we had to correct it before moving on to the next step.
Here are the main guidelines that caused us problems:
Guideline 5.2.3 - Legal
Your app contains content or features that may violate the rights of one or more third parties. Specifically, your app provides potentially unauthorized access to third-party audio or video streaming, catalogs, and discovery services.
Despite providing Apple with a document listing the authorised platforms in the iOS app, this was not enough to convince them. We therefore replied:
The platforms listed in the PeerTube application have granted the right to list and access their video content to the PeerTube application.
These authorizations are listed in the document "Authorized Platforms for PeerTube App".Can you explain what kind of evidence we need to provide to show that we have the right to access this content?
The document attached was exactly the same as the one submitted when the application was filed.
Guideline 3.1.1 - Business - Payments - In-App Purchase
Apple reported a link to the website joinpeertube.org in the app, which contains a donation button. This simple external link was enough to justify rejection.
In our initial response, we explained that all donation links now open an external page in the browser and that no collection is made within the app itself. We emphasised that this approach complied with the App Store guidelines since the donation process was completely separate from the app's functionality. Despite this clarification, Apple was not convinced.
Looking back at the App Store Guidelines, I found a paragraph in our favour:
Section 3.2.2 (iv) : Apps that are not approved nonprofits or otherwise permitted under Section 3.2.1 (vi) may collect charitable donations outside of the app, such as via Safari or SMS.
I therefore sent another message to the validation team, reiterating that the app does not collect any donations internally and that all support links open an external page in Safari, in accordance with Section 3.2.2 (iv) of the App Store Guidelines, which permits this for non-charitable apps. I therefore requested a reassessment of the decision or clarification of any other issues.
🎉 Result: The PeerTube app has been officially released on iOS!
Since then, I have submitted six updates to PeerTube, all of which have been approved without issue — including the one that introduced the login feature.
Each update was approved within a few hours — at most, within 24 hours.
The App Store is never easy, but with patience and careful reading of the guidelines, it works.
F-Droid: another adventure
Once the Apple stage was complete, I moved on to submitting to F-Droid.
Here, the problem wasn't with the guidelines, but with the process.
The official documentation is rather sparse and I struggled to find a comprehensive resource for a Flutter project. So I relied on:
- the 'Quick Start' documentation: https://f-droid.org/docs/Submitting_to_F-Droid_Quick_Start_Guide/
- the developer FAQ: https://f-droid.org/docs/FAQ_App_Developers.html
- and, above all, analysis of other Flutter apps already on F-Droid.
Adapting to how F-Droid work
F-Droid has specific requirements:
- The build must be reproducible and completely free.
- All external dependencies must be verifiable or removable.
- Any anti-features, i.e. limitations that do not correspond to the ideals of free software, must be declared.
Example: TetheredNet
The PeerTube application uses two Framasoft-maintained services by default:
- instances.joinpeertube.org to list available instances
- SepiaSearch to search from a local account.
As these services are not configurable by the user, this was considered an 'anti-feature' of the TetheredNet
type (i.e. connection to a centralised service without the possibility of changing it).
This anti-feature was therefore added during the initial submission.
The good news is that since then, this anti-feature has been removed, as we have made these services customisable in the app.
Overcoming the blockage caused by an obsolete dependency
Before reaching validation, we encountered an obstacle related to a dependency that was used to manage the local database. Although this library was popular when the initial choice was made, it is no longer maintained and does not offer a version compatible with the latest Flutter version required by F-Droid to guarantee build reproducibility. This prevented the application from being compiled on the F-Droid infrastructure and made publication impossible.
Following an analysis, we concluded that the most sustainable and secure solution was to replace the obsolete dependency with a maintained alternative that met F-Droid's requirements. Although this required a partial rewrite of the local data management, it unblocked the situation and ensured the long-term stability of the project.
The merge request submission
After several iterations, we were finally able to submit our app to F-Droid.
You can view the merge request (MR) here:
https://gitlab.com/fdroid/fdroiddata/-/merge_requests/17235
You can also view the final configuration of the PeerTube app on F-Droid (file metadata/*.yml):
https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/org.framasoft.peertube.yml
Using F-Droid requires patience and rigor, but it also provides a better understanding of the challenges of free software and decentralisation.
Ultimately, this experience reminds us that making an application available online is a skill in its own right. This skill is often overlooked, yet it is nevertheless essential and requires time, rigor and a variety of skills.
We are therefore particularly happy and proud to offer PeerTube on the major app stores and make this project accessible to as many people as possible.
Finally, don't forget that crowdfunding for the development of the PeerTube app is still ongoing until 17 June 2025!