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.
Related
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 am new to this and still trying to get a feel for the best way to do things with MVVM. I can't find an answer with Google.
For convenience, I have created extensions on multiple custom classes, e.g.,
public static AppointmentLabel ToLabel(this textblockPatient tbp)
{
return tbp.appointmentlabel;
}
In my MVVM model, I have placed these extensions in the Model as they seem to convert one source of information into another. However, some of the custom classes are UserControls and live in the View. Doing it this way would require the Model to "know" something about the View, as the above textblockPatient is a UserControl.
How is this done within a MVVM pattern? Are extensions considered to be an exception to the pattern?
Thanks for any help.
In my opinion this is not a mvvm related thing. I would suggest that you put your extension classes near to the classes they extend. By doing it so you reach some level of cohesion. Sometimes it make sense to put the extensions in a seperate project. For example if you know you want need that extensions all the time and you want to have a small codebase or faster compile time.
I'm having a little bit of a hard time getting into mvvm. I'm writing a simple app, Notebook. I have one viewmodel, it's name is actually ViewModel. It has an ObservableCollection of Notes inside and methods to save and load those from Isolated Storage. My only Model is Note.cs, it implements INotifyPropertyChanged and I'm of course RaisingPropertyChanged.
I've also got two view, both of them are user controls. One to display list of notes and one to edit the one chosen from the list.
My questions are:
Where do I create an instance of my vievmodel?
How should I implement going from the page with list of notes to the page with detailed view after choosing one Note to edit? At the
moment I'm saving the index of Note in App.xaml.cs, going to the next page and setting
the DetailedView DataContext to the right Note in OnNavigatedTo, but
I don't think it's actually the perfect solution.
Where should I save my Notes? I guess Application_Closing in App.xaml.cs is the right place to do it, but I'd have to have my viewmodel as a global object there, is this the right approach?
Additional question:
I have to add possibility to group notes. I guess that class Group with dictionary (GroupName, howManyNotes) is going to be allright since I don't have to be able to for example write all notes from selected group. Do you think there's a better approach I should think about?
Thanks for respones,
Michał.
I would suggest you take a look at Calibrun.Micro which is a great framework for MVVM. You can get some sample from the CodePlex.
I have used that in a bunch of Project, and will give you flexibility in case if your project grows in size.
Google for Caliburn.Micro sample and you will find a number of sample for all technologies like WPF, Silverlight, Windows Store, Windows Mobile.
Caliburn.Micro CodePlex
Ladies and gents,
I'm having a brain-itching issue with something I deem rather simple.
The case is as follows:
We created a native iOS app, and we want to create some customised versions of the app using the same source and resources. The project is rather large though, so creating multiple targets and linking against almost a 100 files would be overkill in my opinion. So I figured that it would probably be the best idea to create these customised versions of this app using a statically linked library of the original source. So I created multiple types of statically linked libraries using the many solutions our fellow developers provide on the internet. I've come across Jeff Verkoeyen's tutorial and the iOS Universal Framework, both providing me with an excellently built framework including my UIStoryboard files.
There's only one problem, after including the framework and finding the UIStoryboard files I've managed to get everything running. But after running the application the app instantly crashes notifying me that it couldn't find the custom classes I've used in the UIStoryboard to make the app work.
For instance, I've made subclasses for UIViewController (of which all my other ViewControllers inherit), so I could use my code more optimal. The actual subview (BaseViewController) is not to be found by the UIStoryboard. I'll have to note that the actual class files (.h and .m) are inside the framework I've created using any of the above methods.
So, what am I to do now. I really need a solution for either this problem or a hint to another solution that would be fitting for my current problem, which is; I want to create customised versions of apps using a single code base.
Thanks in advance!
Bryan
I'm going to developer two very similar apps, the logic is absolutely the same, but api calls base URLs, texts and UI graphics( such as backgrounds etc) will be different, but the all views will be the same (buttons, labels in the same places). It's quizes apps.
How to do it in the smart way? To not duplicate code etc.
I thought about to setup workspace, add bundles with UI, plists with texts and URL's, and than based on project name or identifier use one of the bundles, etc.
Maybe somebody can share smth else? More efficient way.
Thx.
I thought about [...] adding bundles with UI, plists texts and URL's
You wrote your own answer. Additionally you setup two targets. One for each project. Within the target you define an envorinment variable, which you can use in your code to switch between the bundles / URLs.
You should write a Helper Class to get the Ressources. That helper class checks the environment variable and gives back the correct ressource.
(You may want to write categories for UIImage and NSURL and write your own NSLocalizedString version. With that you don't need to check any conditions/settings anywhere else in your code.)