I have completed Reso Coder tutorial about Clean Architecture with TDD in Flutter Apps. But there are two points interesting for me:
If we have global widgets like Loading, Failure, Empty Case and so on, in which layer and how we can store them to access from any feature? is it okay to create folder like widgets in core folder to store these widgets?
If we have the same API calls, or same local data in different pages, in different features, how can we store them? is it okay to create independent features that have not views itself, just contains domain and data layer for other features?
This is my repository:
https://github.com/thisisyusub/tdd-learn-example
By checking your repo I'm guessing you are talking about your FailureWidget and LoadingWidget and by "global widgets" you meant widgets used in multiple features of your application. Now to answer your questions :
In my opinion you can definitely put widgets shared in multiple features in the core/ folder but I would recommend to keep some sort of coherence with your different layers. By that I mean that widgets should be putted inside a presentation subfolder because only your presentation layer should depend on those.
lib/
|- core/
| |- presentation/
| | |- loading_widget.dart
| | |- failure_widget.dart
Same goes for API calls you want to re-use in multiple features, you can put them inside a data/ subfolder of core/.
lib/
|- core/
| |- data/
| |- data_sources/
Related
I am trying to implement multiple flavors(something like flavors, cause the flavors are from android) in flutter web but I can't find the proper way.
What I want to do:
1. I want to change the application's name.
1. I want to have different theme, colors, etc.... inside the index.html file.
I added dart-defines to customize dynamically the app's theme, but few things remain the same, like the styling that I have in index.html file(I changed it in order to have a loading page instead of the white screen).
I also tried to create two folders inside the web folder, but still, flavors don't work.
Is there any solution for this matter out there?
Has anyone faced this?
As of today, Flutter Web does not directly support flavors.
As a workaround though, flavors can be achieved by creating different builds though, in your case different index.html files, in your CI pipeline. In essence you can now have different apps for different flavors.
Save index.html as a template (ex. index.html.template) in your project with all modifiable configs (title, theme, colors, etc.) defined as environment variables, and replace these environment variables to generate the actual index.html during the build.
Now you can control these builds to have different configs basis your flavors and fulfil your use case.
For example -
To control application name, you can use,
<title>"${CUSTOM_TITLE}"</title>
and configure this CUSTOM_TITLE based on the flavor, during pipeline build.
Similar control issue and solution was answered here: https://stackoverflow.com/a/71538173/11675085
My query is how can we build multiple apps with different UI's from one project.
Example:
HomePage has (home1, home2, home3) 3 different Ui's , i want to add home1 for one app, home2 for other app and so on.
So that i can create similar apps with slightly different UI.
How can we configure the same in flutter?
Any help would be appreciated.
You can use flavors for it. In few words, you should create a project with common features and separate it by packages (because Google Play doesn't support apps with the same package name). Your features and different screens (and icons and other app specific resources) separated in flavors, and when you build specific flavor - you build separated app (in your case). In code you can split features by flavor type (find more in this question).
or "How to decouple UI from business logic in Delphi?"
Each target platform has its own set of native firemonkey controls (Windows=VCL, MacOS=TMS mCL, Android=D.P.F, iOS=TMS iCL and D.P.F). The new FireUI (multi-device form designer) is a great solution for styled components, but not for native components because it still requires the same component on the master pane to support all platforms. As you cannot mix them on the same form, it completely breaks the whole idea with Delphi.
A lot of developers would say that Delphi is the broken approach, see "Why FireMonkey is so fundamentally wrong in every aspect". However, the premise for this question is NOT to argue against Delphi, but to get the best results out of what it does offer.
The conclusion is then that for each form in your application you have to make a separate form for each target platform. This leads to these questions:
Challenge 1: How to include different form files in your project depending on your target platform?
Solution 1: include all of them, i.e. MainForm_IOS.pas, MainForm_Android.pas, MainForm_Win, MainForm_OSX.pas, and then use compiler directives inside the files, so only the content of one of the files is active. Disadvantage: a large application can have many forms (we have around 40), so we are talking about a large number of included files.
Solution 2: Do not include them in the project, but instead just place them in seperate folders. Then you can add the matching folder to the search path for each target platform. Disadvantage: They will not show up in the Project Manager, so it will slow down the workflow every time you need to find a file.
Solution 3: Create a project for each target platform. Disadvantage: Every time you add new units or change common project settings you have to (remember to) apply it to all projects.
Update: As suggested in the Malcom Groves video, placing all the business logic in a package will remove the disadvantage from Solution 3. So I consider solution 3 as the best approach.
Challenge 2: How to connect the different device forms to the (same) business logic?
Possible solution: Create a "Helper" class that contains all the code you would normally have in the form unit.
Update: This "Helper class" is actually what the MVVM calls a ViewModel. What I need seem to be a MVVM framework that can support the databinding. I have made another question about that.
Any input and suggestions about best practice are welcome.
For challenge 1:
You can conditionally link in your FireMonkey form resources depending on the compile target:
{$R *.Windows.fmx MSWINDOWS}
{$R *.Macintosh.fmx _MACOS}
etc.
This is excatly what the XE7 Multiview designer does, but I see nothing against using this mechanism to link whole form files conditionally in to your executable. Of course you might also want to ifdef the corresponding units in your project file.
For challenge 2: Just use some form of Model View Controler logic. So your platform dependant forms will talk to a platform independant controler.
I'm developing by Openui5 a portal. My portal have 2 apps. I I have organized the code in folders:
root
|
|____app1
|____app2
|
|____appN
In each app folder I have "master" folder, "detail" folder...etc..
What is the best way to organize the code?
Now I have an external structure of SplitView from which I call the sub-apps
(simply, when I select the app name from the list in the master column I replace the general master-detail pages - or the current app master-detail pages - with master-datail pages of the app selected)
Thi is the right way to develop a multi-app "portal"?
Definitely not the worst approach :)
You might also want to think about using UI5s Component concept. It allows for a better separation of apps by providing dedicated Router and EventBus for every component. It also isolates the sub-apps models from each other so that you can have models with same name in every component (handy for i18n/ResourceModel). A component does not even have to live within the same location.
The perfect match for what you plan to do but might be a little oversized though since placing different subviews (master/detail) from a component into the parent component can get a bit tricky.
GL
Chris
What are good ways of building groups/folders?
I've tried by feature (UI for a feature plus model etc) with a common group. I've also tried by UI, model, etc.
The former keeps like things together which fits the iPhone paradigm nicely. The latter means I jump around a bit more.
What do you think?
The standard Xcode MVC folder structure is as follows.
CoreData : Contains DataModel and Entity Classes.
Extension : Contain One class(default apple class extensions+project class extensions.)
Helper: Contain Third Party classes/Frameworks (eg. SWRevealController) + Bridging classes (eg. Obj C class in Swift based project)
Model : Make a singleton class (eg.AppModel - NSArray,NSDictionary, String etc.) for saving data. The Web Service Response parsing and storing data is also done here.
Services : Contain Web Service processes (eg. Login Verification, HTTP Request/Response)
View : Contain storyboard, LaunchScreen.XIB and View Classes. Make a sub folder Cells - contain UITableViewCell, UICollectionViewCell etc.
Controller: Contain Logic or Code related to UIElements (eg. UIButton’s reference+ clicked action)
It's going to be very project dependent. In my last project I had mostly views, and so I organized the views by view-type.
Organizing code by type
Organizing code by type is ok for small projects but it's not a good practice for big ones.
Just imagine you have tons of files and folders organized by type, and when you work on a single feature, you have to open all of the folders. Which can confuse you and you can get lost many times while you scroll through files.
It looks something like on A.G's & Julian B.'s answers.
Organizing code by feature (intent)
Organizing code by feature (intent) is the best practice for big projects and big teams.
Cause usually teams work on a single feature, and they focus only on a single folder or group of files. They don't necessarily have to know about other features and files.
It looks something like this:
AppDelegate
Features
Feature 1
View Controllers
Models
Views
Logic
Feature 2
View Controllers
Models
Views
Logic
Networking
Models
Logic
Extensions
Resources
Also, to mention, this practice and technique (organizing project by feature) are implemented by the greatest companies around the world.