DEV-Android
DEV-Android copied to clipboard
Android - Natively
Proposing: Migrate from a webkit view app to a native android app
Why?: It will bring a variety of things to the community - It will allow for more customization, it will allow for better support and stability. It will allow for more features on the user's end
Goal?: Make the app 100% in kotlin while eliminating the use of webkit.
Challenges?: This will be a massive challenge. We will basically be restarting the entire thing, however it will be very welcomed - it allows for a lot more possibilities. Instead of tailoring towards webkit we get to native control the app. We would have to greatly work with the API developers for oauth, etc.
CC: @bartekpacia
I haven't worked on the mobile side of DEV, so I had @larson-carter drop this issue to facilitate a discussion on their idea.
After a quick chat with @fdoxyz and @maestromac, it seems like there aren't a plethora of reasons this shouldn't be attempted, but we might have a few important things to consider before jumping on this project.
We'll definitely want to get @benhalpern's feedback on this before taking any action. In the case that this doesn't seem like the best option, we might still be able to come up with some great related tasks that don't result in a complete rewrite.
There is no question that a native Android app could provide a better user experience than a WebView can.
I think an important consideration is to not focus on the best case scenario, but to think whether one approach actually does provide a better experience in the long run.
If the app was written natively for Android, consider the following tradeoffs compared to a WebView implementation:
- The team needs Android expertise to continue to maintain the application in perpetuity
- Every new feature implemented on web/iOS needs to be reimplemented on Android separately to achieve feature parity, leading to additional work and significant complexity in release management and planning.
This is not to say natively improving the app is a bad idea, but it's worth considering whether there is an intermediate approach that allows to enhance certain critical parts of the user experience natively, while keeping other parts in WebViews, i.e. a hybrid approach.
Without knowing particular challenges of the app UX, this could look like e.g. implementing the post authoring view, login flow etc natively, while keeping the main content browsing experience WebView-based -- in fact, displaying content is what the web is good at!
If you end up considering a hybrid approach, it might be worth evaluating cross-platformn UI toolkits like Flutter or React Native. Similarly to WebViews, these would of course have some adverse tradeoffs compared to pure native Kotlin as any abstraction always comes with a cost. But, they also come with benefits:
- Dev.to website is already implemented in JS and React, so using React Native for native UI parts would enable developers use their skillset to contribute to both web and mobile codebases and also possibly share code between them (though the value of this is often overestimated)
- Any native enhancements could benefit both iOS and Android apps.
I'm not a project core contributor, so I don't have much context on the team and its constraints, but in any cases the tradeoffs should be considered, and sometimes just because something can be done, doesn't mean it should. Also, sometimes the thing that looks better for the user (e.g. better performance and smoother UI) can actually end up being worse (team is not able to ship new features because there's so much work to make everything work on every platform).
I do however very much agree that the mobile app experience could be a lot better, and if you can identify lower-risk, lower-maintenance approaches, that would be really cool!
Eventually, if this product keeps growing at the rate it is now, a native (or React Native etc) rewrite is a good idea. Just needs to be carried out with full view of the implications.
Disclaimer: I'm not a Practical Dev contributor, came here as @larson-carter was seeking feedback.
Hi everyone, thank you for sharing your thoughts around this idea.
Indeed the WebView approach has been valuable so far since we get almost immediate sync with features released on the website and also the reduced-effort in maintenance for the team, as mentioned by @jevakallio
Without knowing particular challenges of the app UX, this could look like e.g. implementing the post authoring view, login flow etc natively, while keeping the main content browsing experience WebView-based -- in fact, displaying content is what the web is good at!
These ideas and other project maintenance tasks could greatly benefit from Kotlin work without requiring a full rewrite (to either fully native or Flutter/React Native). For example we started to introduce native code via the Javascript Interface for certain features to close the gap where WebViews don't perform as well.
Anyways, just sharing these thoughts and like @jacobherrington mentioned it would be good to wait for feedback from @benhalpern on this.
These ideas and other project maintenance tasks could greatly benefit from Kotlin work without requiring a full rewrite (to either fully native or Flutter/React Native). For example we started to introduce native code via the Javascript Interface for certain features to close the gap where WebViews don't perform as well.
I've never been a fan of write once - push twice. It has a lot of issues in my opinion. I think that it would best best for this upbringing to be done in kotlin
Every new feature implemented on web/iOS needs to be reimplemented on Android separately to achieve feature parity, leading to additional work and significant complexity in release management and planning.
True, however if you weigh the pros and the cons of this approach then the pros for sure out weigh the cons.
If you end up considering a hybrid approach, it might be worth evaluating cross-platformn UI toolkits like Flutter or React Native. Similarly to WebViews, these would of course have some adverse tradeoffs compared to pure native Kotlin as any abstraction always comes with a cost. But, they also come with benefits: Dev.to website is already implemented in JS and React, so using React Native for native UI parts would enable developers use their skillset to contribute to both web and mobile codebases and also possibly share code between them (though the value of this is often overestimated) Any native enhancements could benefit both iOS and Android apps.
I don't think that this will be a great approach. I've never been a fan of React Native, mainly because I appreciate the ability to natively make apps. I believe that it makes more sense performance, size, and skill wise to make it with the respective native languages
Eventually, if this product keeps growing at the rate it is now, a native (or React Native etc) rewrite is a good idea. Just needs to be carried out with full view of the implications.
Yes, this will need to be addressed. Web Views can only go so far until they can't be further developed, that is what inspired this idea.
Not a DEV contributor, just here because I saw a request for feedback.
I'd like to make sure we keep this quote in mind
Premature Optimization Is the Root of All Evil
If there aren't currently issues with performance / size, then it is not a very good argument for a native rewrite.
It will allow for more customization, it will allow for better support and stability. It will allow for more features on the user's end
I think these points would have to further elaborated; what customization would you add that cannot be done just with a WebView? How would users be better supported by a native app, and how would stability be improved with a native app as opposed to a web app? Maybe I'm missing something important, but I don't see any immediate benefits.
I've never been a fan of write once - push twice. It has a lot of issues in my opinion. I think that it would best best for this upbringing to be done in kotlin
I've never heard of write once push twice before, but I'm assuming you're talking about sharing code between the codebases for the website and the apps. If it is not already the case, maybe time would be better spent orchestrating a way for the code to be shared between the site and the app as a Git submodule.
-- in fact, displaying content is what the web is good at
This was a very good point! The core of DEV is its content, and WebViews are a perfectly valid way to express that content to the user.
@larson-carter you certainly make a very passionate case for a native rewrite! As I'm not a project contributor, I won't try to convince you or anyone of the superiority of any approach, and I'll leave the decision making to those who have more skin in the game :)
That said, in the spirit of MLH, I would suggest that when discussing the merits of one approach or the other, we try to make a case why it's better to do it that way.
I've never been a fan of write once - push twice. It has a lot of issues in my opinion. I think that it would best best for this upbringing to be done in kotlin
What you're essentially saying here is that you think the app should be written natively, because you think it would be best for the app to be written natively: a tautology, and not a very convincing argument.
I believe that it makes more sense performance, size, and skill wise to make it with the respective native languages
This here is a better type of reasoning. Performance and (native app binary) size wise, you are correct that native apps can be faster and smaller (though WebViews actually have pretty decent scaling characteristics binary size -wise, as the app bundle doesn't grow linearly as the number of screens grows).
However this focuses purely on low-level technical metrics, and sometimes those metrics are not the ones that matter the most. I've already provided many examples above: development speed over app speed, small team size in exchange for slightly app size, etc.
Which brings me to my point:
True, however if you weigh the pros and the cons of this approach then the pros for sure out weigh the cons.
Just because you say that, doesn't make it true. You may very well even be right, and rewriting this app in Kotlin might be the best possible strategy for users and the business, now and in the future! But I don't know that yet, because you haven't really made the argument why! :)
You say, "if you weigh the pros and the cons of this approach then the pros for sure out weigh the cons". Well, I did weigh them, and in my weighing the cons outweighed the pros!
How is that possible? How did we walk the same steps and end at a different result?
That's the fun part of discussing technical tradeoffs, different people might have different priorities, or they might have the same priorities but different experiences that lead them to different conclusions. So, if you want to convince someone else, whether it's a manager or a fellow developer something, you need to make more of a case than to say "it has best performance". Show why performance matters to the user, and to the business.
If you want to convince others, you also have to listen to their points and address them with actual solutions, and not simply brush past them, or say they don't matter.
And, finally, the one thing that never works in a conversation between two people who disagree about something is leaning on your preferences and saying something should be done, because you like it. It doesn't work, because the other person could just say that they like their other way, and now you're stuck.
At the end of the day, the Practical Dev staff will make a decision, because as the project owners they decide which tradeoffs to choose based on priorities that make sense for them. As they well should. But if you wanted to convince them to follow your plan, I think you would be likelier to get your way with a more reasoned, balanced and facts-driven approach!
Alright, so I'm going to directly compare react native (write once push twice approach) to Android Native (Kotlin or Java)
Sources: https://www.netguru.com/blog/react-native-pros-and-cons https://www.verypossible.com/blog/pros-cons-react-native-app-development https://itcraftapps.com/blog/pros-and-cons-of-react-native-and-native-development/
React Native
Pros:
- One Framework, Multiple Platforms React Native allows you to reuse the codebase (or just a part of it) between iOS and Android. So following the philosophy of write it one time then deploy to both platforms.
- Hot Reloading Thanks to hot reloading, a developer can keep the app running while implementing new versions and tweaking the UI; this makes changes instantly visible without the need for the developer to rebuild the app. It is a major benefit for developers.
- Strong, Open-Source Community React Native seems to enjoy the best of both worlds: a flourishing open-source project with the backing of a major tech company like Facebook.
Cons:
- Less Smooth Navigation it's still in its beta phase. There are often breaking changes in tools and dependencies between versions.
- Native Developers Still Needed The lack of out-of-the-box support for many native app functionalities (e.g. camera, push notifications) used to be a significant issue with React Native development. Implementation of some more advanced features might still require help from iOS and Android developers.
- It's backed by Facebook Ehh. Facebook
- Code and UI Limitations Features that require advanced use of the hardware (e.g. bluetooth, accelerometers, gyroscopes, etc.) will require developers to manually intervene in the underlying native code. As a result, in certain cases React Native can actually add complexity rather than remove it.
- New and not 100% tested Young age makes it subject to ongoing changes and improvements, and any errors in React Native take time to address or require developers to come up with custom solutions or workarounds.
Native - Android
Pros:
- Parental support and security Crucial support from the platform providers, both Google and Apple, gives Native technology the advantage of being dependable.
- Specialized for specific systems, easier to work with Dedicated platform allows writing lower level code, giving better control over the environment. The written code is much easier to debug, analyse and troubleshoot. All this because Native is system specific and, say iOS developer doesn’t have to worry about compatibility with any other system than iOS.
- High performance When talking performance, native (again) leads the race. Native programming allows utilising to the full the capabilities of both the device and the system it’s running. You get access to highest attainable framerate, speed, computing power, graphics support etc..
Cons:
- One product, two problems A project in native technologies is challenging to coordinate and manage. As most developers today work in one or another type of agile methodology, the client’s collaboration is required throughout the project. When dealing with essentially two development teams, getting your head around being a product owner can be tricky.
- Time consuming iOS and Android apps have at the core 2 completely different source codes, which means that not only initial mobile app development is more complex, but also the ensuing maintenance, updates and servicing of the software requires considerably more resources
Both React native and Android-Native:
- They will both need native app developers for both solutions To interact with more advanced things either way you are going to end up interacting with it as you would with the perspective of an native developer.
@larson-carter those are some really good points both for and against React Native, and for and against platform-specific development! I'll take a look at the resources you've included, they look really useful!
However, just pasting that here doesn't really further the discussion much. For one, I don't believe the "two sides" here are React Native vs Kotlin.
In fact, the entire "two sides" mode of thinking is not very helpful, as the discussion is how to best improve the DEV Community app, and as per the initial issue description, whether a full rewrite of the project is the best approach. Apart of an off-hand comment I made about an alternative approach, nobody has proposed using React Native for this project.
Instead of fighting a battle against an non-existent enemy, I would suggest focusing on figuring out how we can best support the DEV app to achieve its goals.
At the moment the most time efficient approach is probably to let for the project maintainers weigh in, as I'm sure they will have valuable input that will help us better understand the priorities and weightings of different approaches based on their plans, constraints and experiences ;)
@jevakallio Great, idea. I'll wait on some maintainers input then we can give some details on improving the app for the community side of things.
Hey folks sorry for not weighing in sooner.
I'm not absolutist on React Native vs Native Android as a discussion, but I am interested in focusing on the highest leverage areas.
I don't think it's the right call right now to be thinking about moving views to fully native because we have a lot of exploration to do in terms of functionality and we sort of need the simplicity of only shipping one version of a lot of our interface decisions on the web side. In the future we could be stable enough with our choices to go native, but IMO webviews work well enough now.
However...
If folks are feeling like they want a challenge...
I think starting to think about the Forem native app (building on the great stuff we've currently built), I think that could be really exciting.
It's essentially the same core functionality of the DEV app, but designed as a wrapper app for all the Forems. This is our end goal and I actually think we could pull it together pretty quickly if we have the right energy in the room, so to speak.
Here's a concept of how I've been thinking about it.
In the bottom of the screen, communities would be displayed alongside nearby ones...
I might be a little silly thinking in these terms but I'm sort of thinking something along these lines but without the 3d flipping...
But if you swipe on the screen you switch to the Forem to the right or left and the menu glides along. The swipe mechanism would be similar to how swiping between views was originated on Snapchat and is used elsewhere (pretty common mobile pattern).
Each view remains just a webview so the app really only has to manage the high level functionality of moving between forems and managing the native bridge stuff. (And also eventually discovering new forems and stuff)....
In the end I think sticking with Android remains sensible to ensure we can always integrate with whatever APIs are needed, and to leverage all the native bridge code we've already written, but I'm not against entertaining a switch up as an idea.
Thanks for starting this conversation @larson-carter.
How do folks feel about everything I said?
Me and @bartekpacia are interested in the Forem app. We just have a few questions:
- Is the app going to be built into the dev to app? Or is it going to be an entirely separate app?
- Has any code been written for this project yet? If so is it private? If not can we start on it ourselves?
- Can we get digital markups of how you would like the UI/UX to look?
Hi again @larson-carter, I'm glad you're both interested in the idea.
I don't believe there's any code up for this at the moment and I personally see this as a separate app, since the branding for Forem would be separate from DEV (the continuity of the DEV app is up in the air as well as soon as this new app is released).
The current app has components/patterns that can be ported and improved when working on this though. Here are some of the concepts I'm referring to:
- We use a custom WebViewClient, which could be renamed to
ForemWebViewClient
or similar. It encapsulates code that extracts the user's ID from the website (for Push Notifications), URL overrides (external URLs are presented modally except for these), and other self-contained logic. - The AndroidWebViewBridge is the entry-point for native functions to be executed from JavaScript.
- A current concern within the team is the directory structure. In this project we have a very modularized directory, which seems great for large (commonly native) projects where Activity/Fragment/Component reuse is key. In this case, being a minimal WebView based app we could benefit from simplifying the directory structure.
These are all ideas that can be shaped along the way and are open to change, specially since there will be differences with the existing app like:
- The list of available Forem instances must be fetched from somewhere (not defined yet) and this impacts the app in a few different ways (i.e. are we reusing a single WebView or instantiating multiple)
- From Ben's sketch a toolbar at the bottom of the screen would be implemented for native buttons/controls, but of course I know more definite digital markups would be very helpful for you
I can't answer all your other questions at the moment, but I'll make sure we get back to you on them since I know they're important for you to work on this.
@fdoxyz Thank you for your reply. I'm going to go part by part and reply!
I don't believe there's any code up for this at the moment and I personally see this as a separate app, since the branding for Forem would be separate from DEV (the continuity of the DEV app is up in the air as well as soon as this new app is released).
I agree that this should be separate from dev. However where will we store the codebase? Will we be able to store it inside of this org and we be added as collaborators? That way we can potentially gain more traction with it being nested under github/thepracticaldev instead of it being under my personal account
I don't think it's the right call right now to be thinking about moving views to fully native because we have a lot of exploration to do in terms of functionality and we sort of need the simplicity of only shipping one version of a lot of our interface decisions on the web side. In the future we could be stable enough with our choices to go native, but IMO webviews work well enough now.
- @benhalpern This is where I'd like more of an explanation. Why wait until you need to make something fully native or migrate to something more powerful. The upkeep/tailoring around one thing here makes it seem very wasteful if you are already starting to realize that you will have to modify your codebase in the future. Eventually as dev.to grows, which it is rapidly, this problem will become more evident.
We use a custom WebViewClient, which could be renamed to ForemWebViewClient or similar. It encapsulates code that extracts the user's ID from the website (for Push Notifications), URL overrides (external URLs are presented modally except for these), and other self-contained logic.
Interesting. This goes back to the WebView vs Native debate. I looked over the kotlin file. Would it not be best to make the Forem app native? Instead of having to rely on a WebViewClient?
A current concern within the team is the directory structure. In this project we have a very modularized directory, which seems great for large (commonly native) projects where Activity/Fragment/Component reuse is key. In this case, being a minimal WebView based app we could benefit from simplifying the directory structure.
This is something that I was wishing someone would bring up. Couldn't we set this up to appear as a fragmented/Activity app? Without having to make the app tailored to WebViews? I feel that eliminating the middle man would make life a lot easier.
The list of available Forem instances must be fetched from somewhere (not defined yet) and this impacts the app in a few different ways (i.e. are we reusing a single WebView or instantiating multiple)
I'd like to hear more about how the instances would work.
From Ben's sketch a toolbar at the bottom of the screen would be implemented for native buttons/controls, but of course I know more definite digital markups would be very helpful for you
Yes! A digital higher quality design that has more details for others to look at will be much appreciated!
Notes/TL;DR
-
Me and @bartekpacia are willing to spend time making this into a 100% functional app. We both value performance and the User's experience.
-
Which is why I'm strongly discouraging the use of WebKits/WebViews then that in my opinion is defeating the purpose of an app. At that point a user would be better off to just open a web browser (hoping that it is mobile optimized).
-
I've learned over the years that instead of tailoring your app around one thing (WebViews/Kit) instead make something else tailored to the app.
-
Would it be possible to do a zoom call after all these questions are answered?
I'll just add that we could use some cross-platform framework (I'd prefer Flutter, I can elaborate on the advantages later on) and get near-native performance and single codebase.
PS It's just me wondering. It seems that the idea is at a very early stage.
The core objective of the Forem mobile app would be to act as a browser for multiple instances, where one could easily switch between communities and read/interact on them. This is probably the main (but not only) reason why using WebViews is the approach we are aiming to follow.
These instances are websites that run a generalized DEV codebase (more details in "What is Forem?" here)
The organization/repo for this new app is not yet configured. This is an organization wide task we're currently sorting out (not just for mobile repos), so we'll still need some time to get it up and running.
I think it's important to note that your questions/suggestions are valid and the discussion quite valuable too. They are valid points in a general sense, but are not exactly aligned with the immediate roadmap/objectives.
I'd say the current design ethos in our README sums it up well with:
By leveraging webviews as much as possible, we can smoothly sync up with our web dev work. And where it makes sense, we can re-implement certain things fully native, or build entirely native features. Life's a journey, not a destination.
As in WebViews make the journey pleasant for us. We have to deal with less friction as the project constantly evolves, making our efforts targeted on the specific areas we want to focus (the opposite of wasteful).
We're aware of the shortcomings of the approach and we're okay with bridging the gap on a "per-feature" basis.
Closing this as it is not required now.