Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to construct a property by generic type in Swift?

I created a generic class in swift and I'd like to initialise an adaptor with the type 'AdaptorType', but I received an compiling error

class Sample<ItemType, AdaptorType> {
    var items = Array<ItemType>() 
    let adaptor = AdaptorType()   //Error: 'AdaptorType' is not constructible with '()'
}

I also tried initialise it in init(), but same problem toke place

class SampleGnericClass<ItemType, AdaptorType> {
    var items = Array<ItemType>() 
    let adaptor : AdaptorType

    init() {
        adaptor = AdaptorType()      //It doesn't work, same error occors here
    }
}

What's the right way to get adaptor property initialised with the generic type AdaptorType? Thank you a lot!

EDIT: Full codes about this question

import UIKit

protocol XYManagedObject {

}

protocol XYNetworkProtocol {

    typealias ManagedObjectType : XYManagedObject

    func object(fromItemDictionary dictionary: NSDictionary?) -> ManagedObjectType?
    func objects(fromEntryDictionary dictionary: NSDictionary?) -> Array<ManagedObjectType>?
    func actionParameters(page: UInt?) -> (action: String, parameters: Dictionary<String, String>?)
    func pageSize() -> UInt? // nil for unlimited
}

class ProductAdaptor : XYNetworkProtocol {

    var filter = Dictionary<String, String>()

    typealias ManagedObjectType = XYProductObject

    func object(fromItemDictionary dictionary: NSDictionary?) -> ManagedObjectType? {
        //... Will return an object here
        return nil
    }

    func objects(fromEntryDictionary dictionary: NSDictionary?) -> Array<ManagedObjectType>? {
        //... will return an array of objects here
        return nil
    }

    func actionParameters(page: UInt?) -> (action: String, parameters: Dictionary<String, String>?) {
        var parameters = filter
        if page {
            parameters["page"] = "\(page!)"
        }

        return ("product_list", parameters)
    }

    func pageSize() -> UInt? {
        return 100
    }
}

class XYDataManager<ItemType: XYManagedObject, AdaptorType: XYNetworkProtocol> {

    var objects = Array<ItemType>()
    let adaptor = ProductAdaptor() //work around, adaptor should be any type conform to XYNetworkProtocol

    func loadPage(page: UInt?) -> (hasNextPage: Bool, items: Array<ItemType>?) {
        let fetcher = XYFetchController()

        let ap = adaptor.actionParameters(page)
        if let fetchedResult = fetcher.JSONObjectForAPI(ap.action, parameters: ap.parameters) {

            let npage = fetchedResult["npage"].integerValue
            var hasNextPage = true
            if !npage || !page {
                hasNextPage = false
            }
            else if npage <= page {
                hasNextPage = false
            }

            let objects = adaptor.objects(fromEntryDictionary: fetchedResult)
            return (hasNextPage, (objects as Array<ItemType>?))
        }
        else {
            return (false, nil)
        }
    }
}
like image 509
Sensheng Xu Avatar asked Jun 12 '14 17:06

Sensheng Xu


People also ask

How do you make a generic function in Swift?

Swift Generic Function // create a generic function func displayData<T>(data: T){ ... } Here, We have created a generic function named displayData() . T used inside the angle bracket <> is called the type parameter.

How do you create a generic type?

To construct a generic type from the generic type definition for a nested type, call the MakeGenericType method with the array formed by concatenating the type argument arrays of all the enclosing types, beginning with the outermost generic type, and ending with the type argument array of the nested type itself, if it ...


1 Answers

Not all objects can be initialized without arguments like you are trying to do. You have to take an initialized instance to the initializer of you class

You may also be able to define your own protocol that requires an empty initializer (by adding init to it) and restrict AdapterType to be of that protocol

like image 94
drewag Avatar answered Sep 28 '22 23:09

drewag