Swift: универсальная функция Realm с <T>как kotlin - PullRequest
0 голосов
/ 19 февраля 2019

Я пишу класс для универсального царства, я уже закончил в Kotlin, сейчас я пытаюсь перевести его на swift, но он более сложный, потому что swift кажется менее гибким, чем Kotlin

Kotlin код, который работает:

inline fun <reified T : RealmModel> fetch(sortedBy: String,
                                          ascending: Boolean = true,
                                          noinline predicate: Query<T>? = null,
                                          completion: (error: RealmFileException?, results: List<T>?) -> Unit) {

    val sort = if (ascending) {
        Sort.ASCENDING
    } else {
        Sort.DESCENDING
    }

    try {
        val results: List<T> = if (predicate != null) {
            realm.where(T::class.java).predicate().sort(sortedBy, sort).findAll()
        } else {
            realm.where(T::class.java).sort(sortedBy, sort).findAll()
        }

        completion(null, results)
        Log.s("Successfully retrieve data (size: ${results.size}): $results")
    } catch (e: RealmFileException) {
        Log.e("ERROR: ${e.localizedMessage}")
        completion(e, null)
    }
}

Код выше идеально.

Теперь вот мой Swift код:

func fetch(object: Object.Type, 
           predicate: NSPredicate?, 
           sortedBy: String, ascending: Bool, 
           completion: (_ error: Error?, _ results: [Object]?) -> ()) {
    do {
        let realm = try Realm()

        let objects: Results<Object>!

        if let predicate = predicate {
            objects = realm.objects(object).filter(predicate).sorted(byKeyPath: sortedBy, ascending: ascending)
        } else {
            objects = realm.objects(object).sorted(byKeyPath: sortedBy, ascending: ascending)
        }

        let objectsArray = Array(objects)

        Log.s("Successfully retrieve data (size: \(objectsArray.count): $results")
        completion(nil, objectsArray)
    } catch let error {
        Log.e("ERROR: \(error.localizedDescription)")
        completion(error, nil)
    }
}

проблема заключается в следующем, в моем быстром коде, в блоке завершения я в настоящее время возвращаю список типа Object

И это меня не устраивает, я хочу быть в состоянии сделать, как в kotlin дать ему тип Tи вернуть в завершение список типа T следующим образом:

func get<T: Object>(completion: (_list: [T]) -> ()){
        ...
        let results = realmResults as T
        completion(results)
}

Но у меня есть несколько проблем: 1 - я не могу создать объект области, подобный этому: realm.objects(T.type) или realm.objects(T.self), я получаю ошибку.

2 - Я не могу привести такой список [Object] как [T] '[Object]' is not convertible to '[T]'; did you mean to use 'as!' to force downcast?

3 - Когда я хочу вызвать такую ​​функцию get<Customer>{ results in }

Не работает cannot explicitly specialize a generic function.Как это сделать, чтобы сделать мою функцию универсальной?

1 Ответ

0 голосов
/ 19 февраля 2019

Сначала измените объявление метода на текущий синтаксис Swift

func get<T: Object>(completion: ([T]) -> Void) {
    // ...
}

Затем компилятор может вывести тип T, если вы укажете этот тип в закрытии get method

get { (customers: [Customer]) -> Void in
    // ... work with `customers`
}

так что тогда вы можете использовать в методе просто

let results: Results<T>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...