Does injecting factory make sense in this scenario (Swinject) - swift

What is the right (cleanest and most concise) way to have PetOwner that can at any later point in program create new instances of Cat?
Let's assume that createAnotherAnimal can be called by PetOwner itself after it gets response to some async request, therefore creating as many instances of Cat as needed at the time of creating PetOwner is not possible.
I solved the problem with injecting factory, but I am not convinced that it is the best way to tackle the problem, what are the alternatives in Swinject?
protocol AnimalType {
var name: String? { get set }
func sound() -> String
}
class Cat: AnimalType {
var name: String?
init(name: String?) {
self.name = name
}
func sound() -> String {
return "Meow!"
}
}
protocol PersonType {
func play() -> String
func createAnotherAnimal() -> Void
}
class PetOwner: PersonType {
var pets: [AnimalType] = []
let petFactory : AnimalFactory
init(petFactory : AnimalFactory) {
self.petFactory = petFactory
}
func createAnotherAnimal() {
let pet = petFactory.factoryMethod()
self.pets.append(pet)
}
func play() -> String {
if(pets.count>0) {
let pet : AnimalType = pets[0];
let name = pet.name ?? "someone"
return "I'm playing with \(name). \(pet.sound())"
} else {
return "No animals"
}
}
}
class AnimalFactory {
let factoryMethod : () -> AnimalType
init(factoryMethod: () -> AnimalType) {
self.factoryMethod = factoryMethod
}
}
// Create a container and register service and component pairs.
let container = Container()
container.register(AnimalType.self) { _ in Cat(name: "Mimi") }
container.register(PersonType.self) { r in PetOwner(petFactory: r.resolve(AnimalFactory.self)!) }
container.register(AnimalFactory.self){r in AnimalFactory(factoryMethod:{ () -> AnimalType in r.resolve(AnimalType.self)!}) }
// The person is resolved to a PetOwner with a Cat.
let person = container.resolve(PersonType.self)!
person.createAnotherAnimal()
print(person.play())

Related

How to correct implement provider logic using generics in Swift

I try to implement logic where some different objects can receive their unique configs.
I have a lot of objects with different types, which can request their own configuration object.
//Provider
protocol ConfigProvider {
func config<R: ConfigReciever>(for reciever: R) -> R.ConfigType
}
class Factory {
}
extension Factory: ConfigProvider {
func config<R: ConfigReciever>(for reciever: R) -> R.ConfigType {
//How switch?
return Config1(info: "hey") as! R.ConfigType
}
}
//Reciever
protocol ConfigReciever: class {
associatedtype ConfigType
var dataSource: ConfigProvider? { get set }
}
struct Config1 {
let info: String
}
class Object1: ConfigReciever {
typealias ConfigType = Config1
var dataSource: ConfigProvider?
func execute() {
let config = dataSource?.config(for: self)
print("\(config!.info)")
}
}
But have some problems with correct implement Provider logic.
I don't know how switch reciever to create correct Config type.
Is this any options?
I know, that i can make this without generics (for example with enum of configTypes), but i don't want to make unnecessary casts.
I would suggest using an intermediate protocol
// Wrapper container
protocol Container { }
extension String: Container { }
extension Int: Container { }
// Implementation
//Provider
protocol ConfigProvider {
func config<R>(for reciever: R) -> Configuration where R : ConfigReciever, R.ConfigType: Configuration
}
class Factory { }
extension Factory: ConfigProvider {
func config<R>(for reciever: R) -> Configuration where R : ConfigReciever, R.ConfigType: Configuration {
return Config1(info: "hey")
}
}
//Reciever
protocol ConfigReciever: class {
associatedtype ConfigType
var dataSource: ConfigProvider? { get set }
}
protocol Configuration {
var info: Container { get set }
}
struct Config1: Configuration {
var info: String
}
class Object1: ConfigReciever {
typealias ConfigType = Config1
var dataSource: ConfigProvider?
func execute() {
let config = dataSource?.config(for: self)
// here you should case into wanted structure:
if let stringInfo = config?.info as? String {
print("\(stringInfo)")
}
}
}
let factory = Factory()
let obj = Object1()
obj.dataSource = factory
obj.execute()

Generic class call function

I am trying to create a wrapper for my API return wrapper class for my project.
these are my classes
class Wrapper<T> {
let message = "Hello World"
let wrapped = T.self
public func getData() -> T.Type {
return wrapped
}
}
class Object {
let number = 100
public func getNumber() -> Int {
return number
}
}
class SecondObject {
let name = "Second Object"
public func getName() -> String {
return name
}
}
What I want to achieve is, is there any way I can call the Object function like this
let example = Wrapper<Object>()
example.getData().getNumber() // <<-- This is not working
let secondExample = Wrapper<SecondObject>()
secondExample.getData().getName() // <<-- This is not working
The error in my playground is this
error: instance member 'getNumber' cannot be used on type 'Object'
If you notice the Wrapper class, there is message property which will be used for all my API return object model
So my goal is, I could simply call the Wrapper class together with my object model class and just call the function that is inside the object model class.
I am still learning about generic in swift. What am I missing here?
You don't set wrapped to anything useful. You ned to set it to an instance of T. So you can pass a Tinto the constructor
class Wrapper<T>
{
let wrapped: T
init(wrapped: T)
{
self.wrapped = wrapped
}
}
Or you can have the class construct an instance of T, but if you want to do that, you need to tell it how to construct the instance. For example:
class Wrapper<T>
{
let wrapped: T
init()
{
self.wrapped = T() // << error!
}
}
won't work because the compiler knows nothing about T, not even if it has an init. You can change that with a protocol
protocol Initable
{
init()
}
class Wrapper<T: Initable>
{
let wrapped: T
init()
{
self.wrapped = T()
}
}
And you can apply the protocol to any type you like with an extension. In most cases the extension can be empty because mot types already have an init() method. For example:
class MyClass
{
init() { /* do stuff */ }
}
extension MyClass: Initable {}
class MyOtherClass
{
init(number: Int) { /* do stuff */ }
}
extension MyOtherClass: Initable
{
init() { self.init(number: 0) }
}
Another option is to supply a closure to the wrapper's init.
class Wrapper<T>
{
let wrapped: T
init(factory: ()-> T)
{
self.wrapped = factory()
}
}
let w = Wrapper() { return Array<Int>() }
Normally you'd only do this if you wanted to create multiple instances i.e. you'd keep a reference to the closure and call it each time you needed a new instance.
class Wrapper<T> {
private var wrapped: T // Storing your object of T type
init(value: T) { // init with instance of T
wrapped = value
}
public func getData() -> T { //returning instance of T
return wrapped
}
}
class Object {
let number = 100
public func getNumber() -> Int {
return number
}
}
let o = Object()
let example = Wrapper(value: o) // Here we creating instance of Wrapper with instance of Object
example.getData().getNumber()
How about this , in your example changing the type of wrapped from non-optional to an optional variable type.
class Wrapper {
let message = "Hello World"
var wrapped : T?
public func getData() -> T? {
return wrapped
}
}
class Object {
let number = 100
public func getNumber() -> Int {
return number
}
}
class SecondObject {
let name = "Second Object"
public func getName() -> String {
return name
}
}
and then using it as below
let example = Wrapper()
example.wrapped = Object()
let result1 = example.getData()?.getNumber() // ()
secondExample.wrapped = SecondObject()
let result2 = secondExample.getData()?.getName()
if let val1 = result1 , let val2 = result2 {
print("result1 = \(val1) result2 = \(val2)" )
}

Vapor 2, One to Many relation

Do you have any example of how to create One to Many relation using Vapor 2?
There are some examples of how to do this, but they use the old version of Vapor.
Thank you for all suggestions.
I have found a solution. Here is simple example of an owner having many cars, maybe will be helpful for someone.
Owner:
final class Owner: Model {
static let idKey = "id"
static let nameKey = "name"
static let carsKey = "cars"
var name: String
let storage = Storage()
var cars: Children<Owner, Car> {
return children()
}
init(name: String) {
self.name = name
}
init(row: Row) throws {
name = try row.get(Owner.nameKey)
}
func makeRow() throws -> Row {
var row = Row()
try row.set(Owner.nameKey, name)
return row
}
}
extension Owner: Preparation {
static func prepare(_ database: Database) throws {
try database.create(self) { builder in
builder.id()
builder.string(Owner.nameKey)
}
}
static func revert(_ database: Database) throws {
try database.delete(self)
}
}
extension Owner: JSONConvertible {
convenience init(json: JSON) throws {
try self.init(
name: json.get(Owner.nameKey)
)
}
func makeJSON() throws -> JSON {
var json = JSON()
try json.set(Owner.idKey, id)
try json.set(Owner.nameKey, name)
try json.set(Owner.carsKey, try cars.all())
return json
}
}
extension Owner: ResponseRepresentable { }
extension Owner: Updateable {
public static var updateableKeys: [UpdateableKey<Owner>] {
return [
UpdateableKey(Owner.nameKey, String.self) { owner, text in
owner.name = name
}
]
}
}
Car:
final class Car: Model {
static let idKey = "id"
static let makeKey = "make"
static let modelKey = "model"
static let ownerIdKey = "owner_id"
var make: String
var model: String
var ownerId: Identifier
let storage = Storage()
var owner: Parent<Car, Owner> {
return parent(id: ownerId)
}
init(make: String, model: String, ownerId: Identifier) {
self.make = make
self.model = model
self.ownerId = ownerId
}
init(row: Row) throws {
make = try row.get(Car.makeKey)
model = try row.get(Car.modelKey)
ownerId = try row.get(Car.ownerIdKey)
}
func makeRow() throws -> Row {
var row = Row()
try row.set(Car.makeKey, make)
try row.set(Car.modelKey, model)
try row.set(Car.ownerIdKey, ownerId)
return row
}
}
extension Car: JSONConvertible {
convenience init(json: JSON) throws {
try self.init(
make: json.get(Car.makeKey),
model: json.get(Car.modelKey),
ownerId: json.get(Car.ownerIdKey)
)
}
func makeJSON() throws -> JSON {
var json = JSON()
try json.set(Car.idKey, id)
try json.set(Car.makeKey, make)
try json.set(Car.modelKey, model)
try json.set(Car.ownerIdKey, ownerId)
return json
}
}
extension Car: ResponseRepresentable {}
extension Car: Preparation {
static func prepare(_ database: Database) throws {
try database.create(self) { builder in
builder.id()
builder.string(Car.makeKey)
builder.string(Car.modelKey)
builder.foreignId(for: Owner.self)
}
}
static func revert(_ database: Database) throws {
try database.delete(self)
}
}
extension Car: Updateable {
public static var updateableKeys: [UpdateableKey<Car>] {
return [
UpdateableKey(Car.makeKey, String.self) { car, make in
car.make = make
}
]
}
}

Accessing Class Variables by enum

I have following code which basically defines enum for different companies and different methods for each company.
protocol Fetcher {
func getDetail()
static var idRegex:String {get}
}
class FooFetcher:Fetcher {
static var idRegex = "(^\\d{5}$)"
var company = Company.Foo
init (name:String?, id:String) {
println("Name: \(name) id: \(id)")
}
func getDetail() {
println("Foo Get detail")
}
}
class BarFetcher:Fetcher {
static var idRegex = "(^\\d{11}$)"
var company = Company.Bar
init (name:String?, id:String) {
println("Name: \(name) id: \(id)")
}
func getDetail() {
println("Bar Get detail")
}
}
enum Company:Int {
case Foo
case Bar
func fetcher(name:String?, id:String) -> AnyObject {
switch self {
case Foo:
return FooFetcher(name: name, id: id)
case .Bar:
return BarFetcher(name: name, id: id)
}
}
}
var compList = [Company.Foo , Company.Bar]
How can I get idRegex by using compList array only? I don't want to create another array like [FooFetcher.idRegex,BarFetcher.idRegex] because it will bloat the file. I want to use enum because it is easy to store their rawValue with Core Data.
I also wonder how to write better fetcher function for Company enum. Currently I use fetcher function like below
var company = Company.Foo
var strategy = company.fetcher("Some name", id: "Some id") as! Fetcher
strategy.getDetail()
AnyObject does not support Fetcher, in the company.fetcher function instead of returning AnyObject is -> Fetcher
enum Company:Int {
case Foo
case Bar
func fetcher(name:String?, id:String) -> Fetcher {
switch self {
case .Foo:
return FooFetcher(name: name, id: id)
case .Bar:
return BarFetcher(name: name, id: id)
}
}
}
FOO also there corresponds almost .foo
Along with eliasRuizHz's answer, add a new regex method to the Company enum.
func regex() -> String {
switch self {
case .Foo:
return FooFetcher.idRegex
case .Bar:
return BarFetcher.idRegex
}
}
The two responses both provide good contributions. For example, returning a Fetcher rather than AnyObject makes complete sense, as does a regex() function. The thing that I query, however, is whether you could use enums with associated values rather than this enum + class approach, but putting that to one side and answering the question in hand if you really want to directly access the .idRegex from an instance then it needs to be a regular instance variable not a class variable. One way to have it both ways is to return the type variable through an instance variable like so:
protocol Fetcher {
func getDetail()
var idRegex:String {get}
static var regex:String {get}
}
class FooFetcher:Fetcher {
static var regex = "(^\\d{5}$)"
var idRegex:String { return FooFetcher.regex }
var company = Company.Foo
init (name:String?, id:String) {
println("Name: \(name) id: \(id)")
}
func getDetail() {
println("Foo Get detail")
}
}
class BarFetcher:Fetcher {
static var regex = "(^\\d{11}$)"
var idRegex:String { return BarFetcher.regex }
var company = Company.Bar
init (name:String?, id:String) {
println("Name: \(name) id: \(id)")
}
func getDetail() {
println("Bar Get detail")
}
}
enum Company:Int {
case Foo
case Bar
func fetcher(name:String?, id:String) -> Fetcher {
switch self {
case Foo:
return FooFetcher(name: name, id: id)
case .Bar:
return BarFetcher(name: name, id: id)
}
}
}
var compList = [Company.Foo, Company.Bar]
var company = Company.Foo
var strategy = company.fetcher("Some name", id: "Some id")
strategy.getDetail()
strategy.idRegex
Edit Responding to Query
If you want the fetcher to not necessarily initialize an instance then set whatever requirement there is to determine whether a value or nil is returned.
enum Company:Int {
case Foo
case Bar
func fetcher(name:String?, id:String) -> Fetcher? {
switch self {
case Foo:
if FooFetcher.regex == "(^\\d{11}$)" {
return FooFetcher(name: name, id: id)}
else {return nil}
case .Bar:
if BarFetcher.regex == "(^\\d{11}$)" {
return BarFetcher(name: name, id: id)
}
else {return nil}
}
}
}
var compList = [Company.Foo, Company.Bar]
var company = Company.Foo
var strategy = company.fetcher("Some name", id: "Some id")
strategy?.getDetail()
strategy?.idRegex

get the type/class of a property from its name in swift

Lets say I have this class:
class Node {
var value: String
var children: [Node]?
}
If I have the name of one of its properties (for example "children") how can I get its type? (In this case [Node]?)
I imagine having a global function like below will solve my needs:
func typeOfPropertyWithName(name: String, ofClass: AnyClass) -> AnyClass? {
//???
}
// Example usage:
var arrayOfNodesClass = typeOfPropertyWithName("children", Node.self)
Swift 2 (Note: Reflection changed):
import Foundation
enum PropertyTypes:String
{
case OptionalInt = "Optional<Int>"
case Int = "Int"
case OptionalString = "Optional<String>"
case String = "String"
//...
}
extension NSObject{
//returns the property type
func getTypeOfProperty(name:String)->String?
{
let type: Mirror = Mirror(reflecting:self)
for child in type.children {
if child.label! == name
{
return String(child.value.dynamicType)
}
}
return nil
}
//Property Type Comparison
func propertyIsOfType(propertyName:String, type:PropertyTypes)->Bool
{
if getTypeOfProperty(propertyName) == type.rawValue
{
return true
}
return false
}
}
custom class:
class Person : NSObject {
var id:Int?
var name : String?
var email : String?
var password : String?
var child:Person?
}
get the type of the "child" property:
let person = Person()
let type = person.getTypeOfProperty("child")
print(type!) //-> Optional<Person>
property type checking:
print( person.propertyIsOfType("email", type: PropertyTypes.OptionalInt) ) //--> false
print( person.propertyIsOfType("email", type: PropertyTypes.OptionalString) //--> true
or
if person.propertyIsOfType("email", type: PropertyTypes.OptionalString)
{
//true -> do something
}
else
{
//false -> do something
}
Reflection is achieved in Swift using the global reflect() function. When passing an instance of some type to reflect() it returns a MirrorType, which has a range of properties allowing you to analyze your instance:
var value: Any { get }
var valueType: Any.Type { get }
var objectIdentifier: ObjectIdentifier? { get }
var count: Int { get }
var summary: String { get }
var quickLookObject: QuickLookObject? { get }
var disposition: MirrorDisposition { get }
subscript(i: Int) -> (String, MirrorType) { get }
This seems to work:
func getTypeOfVariableWithName(name: String, inInstance instance: Any) -> String? {
let mirror = reflect(instance)
var variableCollection = [String: MirrorType]()
for item in 0..<mirror.count {
variableCollection[mirror[item].0] = mirror[item].1
}
if let type = variableCollection[name] {
let longName = _stdlib_getDemangledTypeName(type.value)
let shortName = split(longName, { $0 == "."}).last
return shortName ?? longName
}
return nil
}
Here's some example code on SwiftStub.
Edit:
The result for optional values is only "Optional".
The result for arrays is only "Array".
The result for dictionaries is only "Dictionary".
I'm not sure if it is possible to extract what kind of optional/array/dictionary it is. But I guess this would also be the case for custom data structures using generics.
Building on #PeterKreinz answer I needed to be able to check types of inherited properties as well so added a little to his above code:
extension NSObject {
// Returns the property type
func getTypeOfProperty (name: String) -> String? {
var type: Mirror = Mirror(reflecting: self)
for child in type.children {
if child.label! == name {
return String(child.value.dynamicType)
}
}
while let parent = type.superclassMirror() {
for child in parent.children {
if child.label! == name {
return String(child.value.dynamicType)
}
}
type = parent
}
return nil
}
}
Hope this may help someone.
Swift 3 update:
// Extends NSObject to add a function which returns property type
extension NSObject {
// Returns the property type
func getTypeOfProperty (_ name: String) -> String? {
var type: Mirror = Mirror(reflecting: self)
for child in type.children {
if child.label! == name {
return String(describing: type(of: child.value))
}
}
while let parent = type.superclassMirror {
for child in parent.children {
if child.label! == name {
return String(describing: type(of: child.value))
}
}
type = parent
}
return nil
}
}
The solution provided by #peter-kreinz using Swift's class Mirror works beautifully when you have an instance of a class, and want to know the types of the properties. However if you want to inspect the properties of a class without having an instance of it you might be interested in my solution.
I have a solution that finds the name and type of a property given any class that inherits from NSObject.
I wrote a lengthy explanation on StackOverflow here, and my project is available here on Github,
In short you can do something like this (but really check out the code Github):
public class func getTypesOfProperties(inClass clazz: NSObject.Type) -> Dictionary<String, Any>? {
var count = UInt32()
guard let properties = class_copyPropertyList(clazz, &count) else { return nil }
var types: Dictionary<String, Any> = [:]
for i in 0..<Int(count) {
guard let property: objc_property_t = properties[i], let name = getNameOf(property: property) else { continue }
let type = getTypeOf(property: property)
types[name] = type
}
free(properties)
return types
}