ActiveRecord like reflection in swift - ios

I was wondering how to accomplish an active record like (not with core data, but with rest, but this part I don't think will be an issue).
The issue its that don't understand well the reflection in swift, and my goal its to have a base class called Collection like (just prototype not really working code here):
public class Collection
{
public var Id: String
public static func Name () -> String
{
// accomplished but not with static method
}
public static func Find () -> [ChildClass] // the child class how can I obtain dynamically?
{
// restful things
return [ChildClass, ChildClass, ...] // rest result maped from json
}
public static func FindById (id : String) {}
// also Save && Delete methods
}
This kind of things I accomplish in c# with WSD-Data exactly in this class
So the usage maybe will:
public class User : Collection
{
public var FirstName: String
public var LastName: String
}
or c# like (dunno if this can be done in swift)
public class User : Collection<User> // we pass user as reference class c# like
{
public var FirstName: String
public var LastName: String
}
I hear also other alternatives to get this done, because don't know so well swift and the way that things are done with it.

Related

Swift override var inheritance

I am trying to do something like this in Swift.
public class BaseModel {
}
public class SubModel:BaseModel {
}
public class BaseClass {
public var model:BaseModel
init(_ model:BaseModel) {
self.model = model
}
}
public class SubClass: BaseClass {
override var model:SubModel
}
But the complier is not allowing me to override model object with a subclass. Is it possible to achieve something like what I am trying to do above in Swift using inheritance?
As written, this wouldn't be type-safe. Your interface requires that subclass.model = model has to work for any model (and in this specific example, SubClass(model) also is "legal" for any model because it's currently inheriting the init).
What I believe you really mean is that all BaseClass can return a Model, but SubClass can only be set with a SubModel.
How you fix this depends heavily on what the users of SubClass look like and why you're reaching for inheritance. As a rule, you should be hesitant to reach for inheritance in Swift. It's fully supported, but Swift tends to prefer other tools than class inheritance.
A common solution for this specific example would be a generic, for example:
// Place any general Model requirements here.
public protocol BaseModel {}
// Just marking things final to emphasize that subclassing is not required
// These can all also be structs depending on if you need values or references
public final class SubModel: BaseModel {}
public final class BaseClass<Model: BaseModel> {
var model: Model
init(_ model: Model) {
self.model = model
}
}
// You can typealias specific instances if that helps
// With this, the syntax is extemely close to what you were trying to do
typealias SubClass = BaseClass<SubModel>
let sc = SubClass(SubModel())
let model: BaseModel = sc.model
// But, it's type safe
public final class OtherModel: BaseModel {}
sc.model = OtherModel // Cannot assign value of type OtherModel to type SubModel
let bad = SubClass(OtherModel()) // Cannot convert value of type 'OtherModel' to expected argument type 'SubModel'
If BaseClass and SubClass were more complex, and had more internal logic to them, then you could move up to protocols for these, but it would depend on the particular problem you were solving. I'd generally start with generics for the situation you're describing.
You cannot change the types of stored properties in Swift. But covariant overrides are fine for methods and computed properties. So as long as you make model a computed property, you can use inheritance here, but you must be very careful when doing this to avoid crashes.
The simplest approach is to just add a new property with its own name to SubClass:
var subModel: SubModel { model as! SubModel }
But to get the overriding behavior you're asking for, you need to make model a computed property:
public class BaseClass {
private var _model: BaseModel
public var model: BaseModel { _model }
init(_ model:BaseModel) {
self._model = model
}
}
Then you can override model in SubClass:
public class SubClass: BaseClass {
public override var model: SubModel { super.model as! SubModel }
init(_ model: SubModel) {
super.init(model)
}
}
But note that this is dangerous. It is possible for BaseClass or a subclass of SubClass to break the invariant, and then this will crash. To fix that, you should make _model a let value, and make SubClass final:
public class BaseClass {
private let _model: BaseModel
public var model: BaseModel { _model }
init(_ model:BaseModel) {
self._model = model
}
}
public final class SubClass: BaseClass {
public override var model: SubModel { super.model as! SubModel }
init(_ model: SubModel) {
super.init(model)
}
}
All of this is awkward and hard to keep correct. It's hard to keep class inheritance correct in all OOP languages, and that leads to a lot of bugs. That's why Swift encourages other tools, like generics, to solve these problems. They're much easier to write correctly, and the compiler can catch your mistakes.

Issue with Protocols with Associated Types in Swift

I have one framework ProviderFramework with the following contents:
public class Provider {
public func fun(some: Model) {
}
}
public class Model {
public let id: Int
init(id: Int) {
self.id = id
}
}
and another UserFramework with the following contents:
public protocol ProviderProtocol {
func fun(some: ModelProtocol)
}
public protocol ModelProtocol {
var id: Int {get}
}
What I want is to make the Provider class conform to the ProviderProtocol class. So in a framework that imports both of the previously mentioned frameworks I have this:
extension ProviderFramework.Model: UserFramework.ModelProtocol {}
extension ProviderFramework.Provider: UserFramework.ProviderProtocol {}
Unfortunately, this results in an error for the second conformance.
So, I tried using an associated types and my ProviderProtocol turned into this:
public protocol ProviderProtocol {
associatedtype T: ModelProtocol
func fun(some: T)
}
and the problematic conformance to this:
extension ProviderFramework.Provider: UserFramework.ProviderProtocol {
public typealias T = ProviderFramework.Model
}
Now there aren't any compile errors, but if I want to use the Protocol as a type like this:
class Consumer {
var provider: ProviderProtocol?
}
I again get an error: 'Protocol 'ProviderProtocol' can only be used as a generic constraint because it has Self or associated type requirements'
I would want to be able to do the last thing. Do I have some bug in my code or if not is there some alternative solution for this problem?
Thanks a lot in advance.
According to the second approach, why not use Provider instead of ProviderProtocol? Since you confirmed typealias T as ProviderFramework.Model in the extension of class Provider.
class Consumer {
var provider: Provider?
}

CRUD methods in custom Swift classes

I'm wondering if it's a good idea to include CRUD methods inside custom Swift classes, or are they better off in a separate class?
For example I have a class called User.swift:
class User {
var firstName: String
var lastName: String
var id: int
}
Now, would it be okay to include the get and create methods here? These methods will make API calls via Alamofire:
class User {
var firstName: String
var lastName: String
var id: int
static func add(user: User) -> User {
let parameters = ["firstName": user.FirstName , "lastName": user.LastName]
return sendRequest(.POST, url: "example.com/users", parameters: parameters)
}
static func getById(userId: Int) -> User {
return sendRequest(.GET, url: "example.com/users/\(userId)")
}
}
Should these methods be in a separate class, like in an ApiHelper class?
My application passes around the User object in arrays and dictionaries in several places, so wondering if it's good to keep it clean with just the properties.
I think better declare such methods in some ApiHelper/Router singletone class, as well as they must work async, work with some parse system (RestKit probably) and return fetched objects via closures with some delay
The different opinions about the right approach often causes a heated discussion. And this also extends to questions whether we should perform validation in the model class (User) or in the controller, how we should handle versions, serialisation, errors, undo/redo, locking, asynchronicity, etc., etc.
And the resulting code should still be clean, comprehensible, extensible, testable and put into a library so that we can reuse it in other projects!
IMHO, there's no right approach. IMHO, I would start with the following principles:
Your User class is seen in your solution as an Entity. An entity has a property ID and possibly other principal methods, for example, it exposes an init which takes a dictionary of attributes where the class/struct instance can be initialised.
That entity also knows about a "Persistent Store", so your User class may also conform to a protocol "Storable", which exposes class and instance methods like save, create, update, delete, query, etc.
This is only the tip of an iceberg what comprises a complete solution. You might look how others have solved this problem. For ideas, see
Use Core Data objects which you populate from the JSON
Implement the Active Record Pattern
Look at some Object Relational Mappers (there are a lot of implementations and libraries). Even though, you need to map from JSON to Objects, these gives some hints.
If you are still not satisfied, take a look at ASP.NET
Leveraging the "Active Record" approach you may start with something like this:
public final class User {
public init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
public var firstName: String
public var lastName: String
public internal(set) var id: Int
}
protocol ActiveRecord {
static func create(object: Self) throws -> Self
static func fetch(id: Int) throws -> Self
static func update(object: Self) throws -> Self
static func delete(id: Int) throws
}
extension User: ActiveRecord {
static func create(object: User) throws -> User {
...
}
static func fetch(id: Int) throws -> User {
...
}
static func update(object: User) throws -> User {
...
}
static func delete(id: Int) throws {
...
}
}

How to implement fluent api in ASP.NET MVC?

I want to implement fluent api to my mvc sites. I got the basics.
So implement object library such as:
public class UIElement{/*...*/}
public class ButtonBase : UIElement{/*...*/}
public class LinkButton : ButtonBase {/*...*/}
public static class Extensions
{
public static T UIElementMethod<T>(this T element, string title)
where T : UIElement
{
return element;
}
public static T ButtonBaseMethod<T>(this T element, string title)
where T : ButtonBase
{
return element;
}
public static T LinkButtonMethod<T>(this T element, string title)
where T : LinkButton
{
return element;
}
}
But how to use it in razor view without some flush method calling.
#Html.UIproject().LinkButton()
.UIElementMethod("asd")
.ButtonBaseMethod("asd")
.LinkButtonMethod("asd")
But it returns the name of the class. I tried to make an implicit operator to MvcHtmlString but it's not called.
Any idea how to achieve this. How to know it's the and of the chain. I like the way how the Kendo UI work.
Thanks,
Péter
Your UIElement classes need to implement the IHtmlString interface. This interface's ToHtmlString method gets called by Razor and should return an HTML-encoded string.
So I would implement this on the abscract base UIElement and create RenderHtml method which can be implemented by the concrete LinkButton, etc. classes:
public abstract class UIElement : IHtmlString
{
public string ToHtmlString()
{
return RenderHtml(); // This should return an HTML-encoded string.
}
public override string ToString()
{
return ToHtmlString();
}
protected abstract string RenderHtml();
}
If you check KendoUI in Reflector/JustDecompile/dotPeek in the WidgetBase class you will see the same pattern.
I haven't tried it, in this particular situation, but you might be able to use an implicit cast to convert from a fluent builder to the object you need (see this blog).

How to use Dependency Injection with Static Methods?

Imagine there is a Customer class with an instance Load() method.
When the Load() method is called, it retrieves order details by e.g.
var orders = Order.GetAll(customerId, ...);
GetAll() is a static method of the Order class and the input parameters are fields defined in the Customer class.
As you can see, Order is a dependency of the Customer class, however, I can't just create an IOrder and inject it there as interfaces can't have static methods.
Therefore, the question is how could I introduce dependency injection in this example?
I don't want to make GetAll() an instance method since it's a static method and need to keep it that way.
For example, I have used utility classes in my design, most of which just contain static methods.
If you must keep the static method, I would wrap the static calls in a Repository object.
Like this:
interface IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ..);
}
class OrderRepository : IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ...)
{
Order.GetAll(customerId,...); // The original static call.
}
}
Now you inject this repository into your Customer class.
(I'm assuming you're doing this so you can inject fake IOrders at runtime for testing purposes. I should say that in general, static methods are a serious obstacle to testing.)
Seeing as your aggregate root for fetching orders is your customer model I would strongly advise you create a customer repository and inject that to whatever service requires it.
Here is an example:
public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException("customerRepository");
}
_customerRepository = customerRepository;
}
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
return _customerRepository.GetOrdersForCustomerId(customerId);
}
}
public interface ICustomerRepository
{
IEnumerable<IOrder> GetOrdersForCustomerId(int customerId);
}
class CustomerRepository : ICustomerRepository
{
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
throw new NotImplementedException();
}
}
Function Pointer Injection
TLDR:
Inject a function pointer into the Customer class. The value of this function pointer can be Order.GetAll in production, and MockOrder.GetAll in tests.
EXAMPLE:
The dependency (problematic static function we depend on):
class Order {
static func GetAll() -> [Order] {
var orders = ... // Load from production source
return orders
}
}
Our dependent class (depends on static function):
class Customer {
func Init(getAllOrdersFunction) { // Arg is a func pointer
self.getAllOrdersFunction = getAllOrdersFunction
}
func Load() {
var orders = self.getAllOrdersFunction()
// Do stuff...
}
}
Production client class (performs the dependency injection):
class BusinessLogicManager {
func DoBusinessLogic() {
var customer = Customer(Order.GetAll) // Prod func injected here
customer.Load()
// Do stuff...
}
}
Testing client class (how unit test can inject a fake dependency):
class CustomerUnitTests {
static func GetFakeOrders() {
var orders = ... // Hardcoded test data
return orders
}
func TestLoad() {
var customer = Customer(CustomerUnitTests.GetFakeOrders) // Fake func injected here
customer.Load()
// Verify results given known behavior of GetFakeOrders
}
}
DISCUSSION:
How you actually inject the "function pointer" will depend on the syntax and features available in your language. Here I'm just talking about the general concept.
This isn't exactly a pretty solution. It would probably be easier if you can change GetAll to be an instance method (perhaps by introducing an OrdersLoader object, or by using Paul Phillips' answer). But if you really want to keep it as a static function, then this solution will work.

Resources