2016-03-11 6 views
1

У меня есть протокол для извлечения объектов базы данных по PrimaryKeyРасширение SignalProducerType в случае, если значение является массивом <SomeProtocol>

typealias PrimaryKey = String 

protocol PrimaryKeyConvertible { 
    var pkValue : PrimaryKey { get } 
    static func pkObject(key: PrimaryKey) -> Self? 
} 

и я хочу продлить SignalProducerType, чтобы иметь возможность работать на SignalProducer.Value того тип.

Таким образом, расширение одного объекта (один, как в не массив) отлично работает и реализуется следующим образом:

extension SignalProducerType 
    where Value: PrimaryKeyConvertible 
{ 
    func fetchOnMainThread() -> SignalProducer<Value?, Error> { 
     return 
     self.map{ (obj: Value) -> PrimaryKey in 
      return obj.pkValue 
     } 
     .observeOn(UIScheduler()) 
     .map{ (key: PrimaryKey) -> Value? in 
      return Value.pkObject(key) 
     } 
    } 
} 

Но когда я пытаюсь реализовать его на массив этих элементов я ударил некоторые проблемы компиляции:

extension SignalProducerType 
{ 
    func fetchOnMainThread<P: PrimaryKeyConvertible where Self.Value == Array<P>>() -> SignalProducer<[P], Error> { //(1) 
     return self.map({ (value: Self.Value) -> [PrimaryKey] in 
      return value.map{ $0.pkValue } //(2) 
     }) 
    } 
} 

(1) я подозреваю, что подпись не передает идею компилятора правильно

(2) производит следующее сообщение об ошибке:

Type of expression is ambiguous without more context

вопрос я пытаюсь решить, как позволить компилятору распознавать SignalProducer работает на Array<P> где Р PrimaryKeyConvertible и имеют .map работать на нем, соответственно ...

мой текущее решение для выдачи массива является реализация с использованием обобщенной функции, которые перечислены ниже:

func fetchOnMainThread<Value: PrimaryKeyConvertible, Error: ErrorType> 
    (signal: SignalProducer<[Value], Error>) -> SignalProducer<[Value], Error> { 
     return signal 
      .map{ (convertibles: [Value]) -> [PrimaryKey] in 
       return convertibles.map { $0.pkValue } 
      } 
      .observeOn(UIScheduler()) 
      .map{ (keys: [PrimaryKey]) -> [Value] in 
       return keys.flatMap{ Value.pkObject($0) } 
     } 
} 

, а затем используется, например:

extension GoogleContact: PrimaryKeyConvertible {...} 

extension GoogleContact { 
    static func fetchGoogleContactsSignal() -> SignalProducer<[GoogleContact], GoogleContactError> { ...} 
} 

и сайт вызов будет, как:

let signal = fetchOnMainThread(GoogleContacts.fetchGoogleContactsSignal()).onNext... 

, где я предпочел бы иметь его в качестве продолжения, где она будет течь, как обычно

GoogleContacts 
    .fetchGoogleContactsSignal() 
    .fetchOnMainThread() 

Update

другой версии от функции, которую я пробовал: (@ J.Wang)

extension SignalProducerType 
    where Value == [PrimaryKeyConvertible] 
{ 
    func fetchArrayOnMainThread2<T: PrimaryKeyConvertible>() -> SignalProducer<[T], Error> { 
     return self 
      .map{ (values: Self.Value) -> [PrimaryKey] in 
       return values.map{ $0.pkValue } 
      } 
      .deliverOnMainThread() 
      .map{ (keys: [PrimaryKey]) -> [T] in 
       return keys.flatMap{ T.pkObject($0) } 
      } 
    } 

} 


    let signal = 
     GoogleContacts 
      .fetchGoogleContactsSignal() 
      .fetchArrayOnMainThread2() //(3) 

(3) Формирует ошибка:

'[PrimaryKeyConvertible]' is not convertible to '[GoogleContact]'

ответ

0

Хм, хотя я не совсем уверен, что проблема есть, но я думаю, что следующая реализация может быть то, что вы хотите.

extension SignalProducerType where Value == [PrimaryKeyConvertible] 
{ 
    func fetchOnMainThread() -> SignalProducer<[PrimaryKey], Error> { 
     return self.map { value in 
      value.map { $0.pkValue } 
     } 
    } 
} 

Попробуйте это:

extension SignalProducerType where Value == [PrimaryKeyConvertible] 
{ 
    func fetchOnMainThread<T: PrimaryKeyConvertible>() -> SignalProducer<[T], Error> { 
     return self.map { value in 
      value.map { $0.pkValue } 
     }.map { keys in 
      keys.flatMap { T.pkObject($0) } 
     } 
    } 
} 
+0

где положение в расширении подписи является хорошей идеей, но в конце концов становится проблемой на втором отображение из [PrimaryKey] назад к [ PrimaryKeyConvertible] –

+0

@EdwardAshak Извините, не знал, что вы хотите его вернуть. Проверьте мое обновление. –

+0

@wang, я сделал, вы должны посмотреть мое обновление выше –

 Смежные вопросы

  • Нет связанных вопросов^_^