Is it better to declare objects globally or just when needed [closed] - swift

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have a few classes i.e. User, Settings... that I use in most of my ViewControllers. Because I use them often, is it better if I have only one instance of them to use globally, or a new instance for each class?
In AppDelegate:
let user = User()
class AppDelegate: UIResponder, UIApplicationDelegate {
...
vs.
In each class:
class TimerViewController: UIViewController {
private let user = User()

For the current state being globally is better
let user = User()
but it's much better to make it a singleton
class Service {
static let shared = Service()
let user = User()
}
so not to confuse other developers when read the code won't know whether this global var is local/instance/global , so being singleton will sort this

My two cents
It is always better to declare it where you actually need instead of declaring it globally. It is good practice to limit the scope the variables that we use so that it gets deallocated and cleared from memory when its job is over. Here, it is clear that there is only one owner for that instance.
Declaring global objects will lead to maintaining global state for the instance properties and since it is open to all classes, it will not be clear which class is changing what.Here, everyone is like owner of this instance.So, It is always better to avoid it.

Related

Child view-models state management with SwiftUI and Combine [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 months ago.
Improve this question
I have a rather larger screen that I am building with SwiftUI and Combine. I am using MVVM with an ObservableObject object acting as the VM. The main view itself is composed of smaller child views, each of which have their own "dummy" view models (that are currently not ObservableObject but rather simply structs) that take in the model and format the data for the component. I have a few questions and I would be curious to hear the community's thoughts:
1. Where should the child view models be stored?
Currently, I expose the child view models as #Published within my main view model (let's call it CheckoutViewModel). I then have a Combine publisher inside CheckoutViewModel that does a few things and updates the VMs:
class CheckoutViewModel: ObservableObject, Identifiable {
// MARK: - Publishers
#Published var detailsViewModel: DetailsViewModel?
#Published var optionsListViewModel: OptionsListViewModel?
// etc...
// MARK: - Private Members
private var subscriptions = Set<AnyCancellable>()
private let repository: CheckoutRepository // DI'd
// MARK: - Actions
func load(productId: String) {
repository.fetchData(forProductId: productId)
.sink(
receiveCompletion: { _ in },
receiveValue: { product in
self.detailsViewModel = DetailsViewModel(fromProduct: product)
self.optionsListViewModel = OptionsListViewModel(fromProduct: product)
}
)
.store(in: &subscriptions)
}
}
Within my CheckoutView, I then call load and have the child VMs passed to the child views:
struct CheckoutView: View {
#ObservedObject var viewModel: CheckoutViewModel
var body: some View {
VStack {
if let detailsViewModel = viewModel.detailsViewModel {
ProductDetails(viewModel: detailsViewModel)
}
if let optionsListViewModel = viewModel.optionsListViewModel {
OptionsList(viewModel: optionsListViewModel)
}
// ... and so on
}
}
}
I am not sure if I love this approach. Something feels odd about publishing these child view models like this.
Should each of these child view models be observable objects on their own that then communicate to the parent view model?
As you can see, once you bring in user interactions (i.e. a user can select an option in the OptionsList), my current approach may fall somewhat short or become unmanageable the larger the view gets.
This leads me to my second question.
2. Who should own the state? How should user interactions be facilitated?
As you can imagine, state in this case becomes very important, and with something like a checkout screen, there may be a lot of state to track. This is where I am totally lost currently. With this approach, I know I can store state directly in CheckoutViewModel, but it may just end up becoming too large and cumbersome to work with.
To deal with user interactions, I've tried passing down bindings directly to the child views and go from there, but that circumvents the child view models and "clutters" CheckoutViewModel with a bunch of state variables (that seems like they should be part of a model, not the view model).
Another approach was using closures in the child views, e.g. if the user selects a new option from OptionsList, call a closure with the option ID and then call the main view model from the view to update the state - but that seemed super cumbersome and I kept thinking there must be a better way to do this.
Maybe some sort of store or similar would be a good idea? I am trying to get an idea of best practices for how child views/child VMs should communicate with their parent.
Conclusion
As you can probably tell, I am a bit lost about proper state management and how to deal with child views using MVVM in SwiftUI. Any guidance or general ideas/suggestions would be greatly appreciated. Is using MVVM in SwiftUI maybe a bad idea in general? As anyone else done something similar, or am I on the completely wrong path here?

Naming Entities and Protocols [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Background
When developing an application, my approach (rightly or wrongly) is to separate the logic into a Framework (Kit)
The reason(s) for this are fairly straight forward ..
• I like being able to test the logic in isolation
• I like that it forces me to forget about the UI and any UI assumptions
• I like that I am free to create the app using a separate UI .. depending on device (iPhone, Watch .. Apple TV .. Command Line Utility)
The Problem
because I like the logic in a separate framework .. I have introduced a complexity in terms of access modifiers (Public, Internal, Private) for classes, structs, enums, methods, properties.
What I have most trouble with is properties (and properties of Entities in particular)
I prefer not to expose the setter to the consumer of the Framework (i.e. the UI Application)
Within a Module I would typically use the.
private(set) var nameOfProperty
approach.
However this isn’t an option to me in entities of a framework.
So for a framework, I would much rather return a Protocol describing the interface of an Entity
.. i.e. it’s writable properties, it’s read-only properties and it’s accessible methods
We (Swift Developers) have been encouraged down the route of naming Protocols according to a behaviour .. however,
.. for example, a Football/Soccer Team Selection framework I wouldn’t want to be passing back and forth something that conforms to ‘Player-able’, ‘Manager-able’, ‘Fixture-able’
.. I want to pass back and forth a ‘Player’, ‘Manager’, ‘Fixture’ (as the consumer would rightfully expect)
Question
What should I be naming my Entity (assuming it conforms to a commonly known as Protocol) ?
Understandably, we can not have a Protocol called protocol Player and class Player
Some Suggested Ideas
Idea 1: Use underscoring within the framework (my most likely approach)
e.g.
public protocol Player {
public var name: String { get }
}
public class _Player: Player {
..
}
Idea 2: Don’t use protocols, but use computed properties instead (not preferred)
e.g.
public class Player {
private var _name: String
public var name: String {
get {
return _name
}
}
Idea 3: Don’t use protocols, because you're the only consumer then trust yourself and make everything public 🤪
e.g.
public class Player {
public var name: String
}
Idea 4: Use a substitute name within the framework (a bit like underscoring)
e.g.
public protocol Player {
public var name: String { get }
}
public class PlayerEntity: Player {
..
}
or
public class PlayerImpl: Player {
..
}
or
public class PlayerObj: Player {
..
}
Personally, I'd go with Player: PlayerProtocol, unless you are going to be using the protocol much more often. There are some examples of this in the standard library, such as StringProtocol and IteratorProtocol.

Swift Structures and classes [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
What does this line means "Swift doesn’t require you to create separate interface and implementation files for custom structures and classes."
link
It is referring to the old C-style way of separating interfaces and implementations in separate .h and .c (.m for ObjC/.mm for ObjC++) files.
In Swift, you no longer need to deal with this - interfaces are generated by the compiler.
For example:
public class Loader {
private let resource: URL
init(resource: URL) { self.resource = resource }
public func load {
//..
}
}
Generates an interface (effectively, an API) with only the public members exposed:
public class Loader {
init(resource: URL)
public func load()
}
The key here is, that there no longer needs to be a separate file maintained by the developer. The interfaces are generated (or not) based on the access control levels defined on your types.
In objective C you have different files for interface called .h file and for implementation of that interface you have .m file
but in swift you have .swift file in which you implement the functionality so you don't need to create two separate files in swift
thats what docs are referring to ... hope it helps
happy coding =)

Name a class which contains other dependent classes [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have a class which will contain list of two dependent classes inside it.
example
Class ActivityHolder{
private ArrayList activityList;
private ArrayList promiseList;
}
My question is how do i name the ActivityHolder class.
[Edit]
I have a class structure as above.And not the wallet and coin scenario.
Like Richard and amal pointed, the class name must be something related to its function.
If it represents a bunch of activities, so it is okay to name it Activities.
Class Activities {
private List activities; // backlog, planned, other better name (more specific)
private List promises;
}

Guidelines for designing classes for dependency injection [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
This question about unit testing best practices mentions designing classes for dependency injection. This got me thinking as to what exactly that might mean.
Having just started working with inversion of control containers I have some ideas on the issue, so let me throw them against the wall and see what sticks.
The way I see it, there are three basic types of dependencies that an object can have.
Object Dependency - An actual object that will be used by the class in question. For example LogInVerifier in a LogInFormController. These should be injected in through the constructor. If the class is sufficiently high level that it requires more than 4 of these objects in the constructor consider breaking it up or at the very least using a factory pattern. You should also consider providing the dependency with an interface and coding against the interface.
A Simple Setting - For example a threshold or a timeout period. These should generally have a default value and be set via a builder of factory pattern. You can also provide constructor overloads which set them. However in most cases you probably shouldn't be forcing the client to have to set it up explicitly.
A Message Object - An object that is handed off from one class to another which the receiving class presumably uses for business logic. An example would be a User object for a LogInCompleRouter class. Here I find it is often better for the message not to be specified in the constructor as you would then have to either register the User instance with the IoC Container (making it global) or not instantiate the LogInCompleteRouter until after you have an instance of User (for which you couldn't use DI or at least would need an explicit dependency on the Container). In this case it would be better to pass in the message object in only when you need it for the method call (ie. LoginInCompleteRouter.Route(User u); ).
Also, I should mention that not everything should be DI'ed, if you have a simple bit of functionality that was just convenient to factor out to a throw-away class, it is probably ok to instantiate on the spot. Obviously this is a judgement call; if I found it expedient to write a class such as
class PasswordEqualsVerifier {
public bool Check(string input, string actual) { return input===actual;}
}
I probably wouldn't bother dependency injecting it and would just have an object instantiate it directly inside a using block. The corollary being that if it is worth writing unit tests for, then it is probably worth injecting.
So what do you guys think? Any additional guidelines or contrasting opinions are welcome.
The important thing is to try to code to interfaces and the have your classes accept instances of those interfaces rather than create the instances themselves. You can obviously go crazy with this, but it's a general good practice regardless of unit testing or DI.
For example, if you have a Data Access Object, you might be inclined to write a base for all DAOs like this:
public class BaseDAO
{
public BaseDAO(String connectionURL,
String driverName,
String username, String password)
{
// use them to create a connection via JDBC, e.g.
}
protected Connection getConnection() { return connection; }
}
However, it would be better to remove this from the class in favor of an interface
public interface DatabaseConnection
{
Connection getConnection();
}
public class BaseDAO
{
public BaseDAO(DatabaseConnection dbConnection)
{
this.dbConnection = dbConnection;
}
protected Connection getConnection() { return dbConnection.getConnection(); }
}
Now, you can provide multilple imlementations of DatabaseConnection. Even ignoring unit testing, if we assume we are using JDBC, there are two ways to get a Connection : a connection pool from the container, or directly via using the driver. Now, your DAO code isn't coupled to either strategy.
For testing, you can make a MockDatabaseConnection that connects to some embedded JDBC implementation with canned data to test your code.