WatchKit Complication: получить данные о сложности от делегата расширения

У меня есть все необходимые данные в моем расширении WatchKit (переданном из приложения iOS).

Я использовал данные WatchKit InterfaceController для заполнения таблицы, которая отлично работает.

Я пытаюсь найти лучший способ получить те же данные в моем WatchKit ComplicationController.

В настоящее время в InterfaceController данные передаются с использованием didReceiveUserInfo:

func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {

    if let beachValue = userInfo["Surf"] as? String {

        places.append(Place(dataDictionary: ["Surf" : surfValue]))

    } else {
        print("Something went wrong")
    }

}

Нужно ли мне вызывать этот же метод WCSession в моем ComplicationController и снова собирать все данные, или есть какой-нибудь более простой способ получить доступ к этим же данным для использования в _8 _? < / em>

Любая помощь приветствуется. Спасибо!

ИЗМЕНИТЬ:

Моя табличная функция:

func makeTable() {

    // Per SO
    let myDelegate = WKExtension.sharedExtension().delegate as! ExtensionDelegate
    let accessVar = myDelegate.places
    self.rowTable.setNumberOfRows(accessVar.count, withRowType: "rows")

    for (index, evt) in accessVar.enumerate() {

        if let row = rowTable.rowControllerAtIndex(index) as? TableRowController {

            row.mLabel.setText(evt.evMat)

        } else {
            print(“No”)
        }
    }

}

person SRMR    schedule 17.10.2015    source источник
comment
Мне интересно то же самое :-) Документы Apple по адресу developer.apple.com/library/watchos/documentation/General/ say: // Получить данные о сложности от делегата расширения. let myDelegate = WKExtension.sharedExtension (). делегировать как! ExtensionDelegate var data: Dictionary = myDelegate.myComplicationData [ComplicationCurrentEntry]! Если бы кто-нибудь мог объяснить новичку ios, как применить это к моему собственному коду, я был бы признателен. В основном данные моего приложения представляют собой массив настраиваемых объектов.   -  person Alex    schedule 19.10.2015
comment
@Alex, да, я тоже смотрел на это в документации и пытался понять это. Я не был уверен, было ли сказано использовать ExtensionDelegate как место для установки WCSession информации (как вы могли бы сделать в AppDelegate для стороны iOS) или что-то еще. Но да, я тоже не совсем уверен в этом. Дай мне знать, если найдешь что-нибудь!   -  person SRMR    schedule 19.10.2015


Ответы (2)


// Get the complication data from the extension delegate.
let myDelegate = WKExtension.sharedExtension().delegate as! ExtensionDelegate
var data : Dictionary = myDelegate.myComplicationData[ComplicationCurrentEntry]!

Выше Документ Apple является просто примером сохранение данных, необходимых для вашего усложнения, в делегате расширения, видя, как вы можете легко получить к нему доступ как синглтон. Ссылка на «myComplicationData» является примером словаря и по умолчанию не является параметром в ExtensionDelegate.

Либо настройте свой собственный класс как синглтон, который хранит данные для ваших часов следующим образом:

// Access by calling:
// Model.sharedModel.modelVal1
class Model {
    static let sharedModel = Model()
    var modelVal1: Float!
    var modelVal2: String!
}

Или используйте делегат расширения в качестве синглтона и добавьте свои свойства в его класс, как показано ниже. Это позволит вам получить доступ к любым переменным, которые вы создаете в своем ExtensionDelegate.

// ExtensionDelegate.swift
class ExtensionDelegate: NSObject, WKExtensionDelegate {
    var dataVar1: Float!
    var dataVar2: String!
    var myDictionary: [String: String]!
}


// ComplicationController.swift
import WatchKit

class ComplicationController: NSObject, CLKComplicationDataSource {

    func someMethod() {
        let myDelegate = WKExtension.sharedExtension().delegate as! ExtensionDelegate
        // Here is an example of accessing the Float variable 
        let accessVar = myDelegate.dataVar1
        let myDict = myDelegate.myDictionary
    }
}

Использование любого из этих способов поможет хранить ваши данные в одном месте, чтобы вы всегда могли получить к ним доступ из любого класса в расширении для часов.

person Antonioni    schedule 02.02.2016
comment
Привет, спасибо за ответ, я попробую это и дам вам знать! - person SRMR; 09.02.2016
comment
Мне не удалось заставить работать ссылку Apple Doc, поэтому я помещаю эти первые две строки в ExtensionDelegate.swift или ComplicationController.swift? (let myDelegate = WKExtension.sharedExtension().delegate as! ExtensionDelegate var data : Dictionary = myDelegate.myComplicationData[ComplicationCurrentEntry]!) - person SRMR; 09.02.2016
comment
Если вы настроите свой ExtensionDelegate, как я, тогда вам придется получать доступ к своим переменным по тому, как вы их называете. Я обновлю этот ответ выше, чтобы показать, как я могу получить доступ к этим переменным. Какие ошибки вы получаете? - person Antonioni; 10.02.2016
comment
В ComplicationController ошибка (и) Значение типа ExtensionDelegate не имеет члена ... для строк let accessVar = myDelegate.dataVar1 и let myDict = myDelegate.myDictionary. Я имею в виду, что в ExtensionDelegate нет myDictionary, но есть dataVar1, поэтому он должен работать без ошибок, но поскольку это не так, я не могу понять, что происходит. Любые идеи? Спасибо! - person SRMR; 11.02.2016
comment
Вам нужно объявить переменные dataVar1 и myDictionary в вашем ExtensionDelegate, как я сделал выше, тогда вы не должны получать эти ошибки. Конечно, вы можете называть их как угодно. - person Antonioni; 12.02.2016
comment
Имеет ли смысл, что я буду получать ошибки, помещая этот код в someMethod, но не тогда, когда я помещаю этот код в func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void))? - person SRMR; 12.02.2016
comment
И данные, которые я получаю в моем InterfaceController методе didReceiveUserInfo, как мне получить доступ к этим данным в моем Complication? Мне нужно положить WCSession где-нибудь в моем ExtensionDelegate или как это работает? Спасибо! - person SRMR; 12.02.2016
comment
Сохраните места вашего массива внутри ExtensionDelegate в качестве переменной, и тогда вы сможете получить к нему доступ из любого Interface контроллера. Таким образом, сохраняя добавленные данные к нему в вашем Interface контроллере и получая доступ к ним с вашего Complication контроллера - person Antonioni; 15.02.2016
comment
Думаю, я начинаю понимать, но позвольте мне убедиться. Так что прямо сейчас у меня var places = [Place]() в моем InterfaceController. Значит, вы хотите переместить строку кода var places = [Place]() на ExtensionDelegate? Так что эта строка кода будет единственной в моем ExtensionDelegate, верно? - person SRMR; 15.02.2016
comment
Верный. Таким образом, вы всегда можете получить к нему доступ с помощью: let myDelegate = WKExtension.sharedExtension().delegate as! ExtensionDelegate, а затем прочитать myDelegate.places или записать в него. - person Antonioni; 16.02.2016
comment
По какой-то причине var places = [Place]() в ExtensionDelegate вызывается первым, когда я запускаю приложение, поэтому, когда я пытаюсь построить свою таблицу, нет элементов (когда он запускает код let accessVar = myDelegate.places, почему это должно быть? Я разместил свой makeTable код выше так что вы можете увидеть это при необходимости. - person SRMR; 17.02.2016
comment
ExtensionDelegate похож на ваш AppDelegate и вызывается первым при запуске приложения. Поэтому изначально у вас будет пустой массив. Вам нужно будет обновить этот массив либо в вашем методе session:didReceiveUserInfo:, либо каким-либо другим методом из WCSession. Вы можете запросить информацию в своем приложении для iPhone и получить ответ с помощью sendMessage:replyHandler:. Я бы посмотрел на WatchConnectivity и посмотрел, какой метод (ы) будет работать лучше всего. - person Antonioni; 18.02.2016
comment
Застрял на связанном вопросе с реализацией части var data : Dictionary = myDelegate.myComplicationData[ComplicationCurrentEntry]!, если у вас есть возможность заглянуть в stackoverflow.com/questions/35542729/ - person SRMR; 22.02.2016
comment
Есть ли способ внутри somemethod обновить myDict, чтобы он не равнялся нулю при доступе из ComplicationController и т. Д.? Я обнаружил, что если я жестко закодирую строку var dataVar2: "String", она станет доступной, потому что она была инициализирована перед запуском WCSession, но поскольку myDict равно нулю до запуска WCSession, мне нужно обновить ее или сообщить ComplicationController об этом обновлении, вы знаете? - person SRMR; 31.03.2016
comment
Когда вы получите данные в session:didReceiveUserInfo:, сохраните данные для вашего усложнения в NSUserDefaults. Таким образом, когда усложнение загружено, вы можете получить доступ к актуальным данным, хранящимся в NSUserDefaults, не полагаясь на то, был ли ваш словарь инициализирован. - person Antonioni; 31.03.2016
comment
Пробовал, но при усложнении запрашиваются данные до session:didReceiveUserInfo:, так что я как бы застрял, не имея ни малейшего представления - person SRMR; 31.03.2016

Что ж, то, что я сделал в своем приложении, - это настроить еще один класс singleton, который будет отвечать за выборку и хранение данных как для моего приложения Watch, так и для усложнения. Но для меня это не лучший способ. К сожалению, я не получил код Apple

var data : Dictionary = myDelegate.myComplicationData[ComplicationCurrentEntry]!

вообще. Я не понимаю, откуда это myComplicationData.

person Alex    schedule 20.10.2015
comment
Да, я все еще пытаюсь понять это. Надеюсь, кто-то налетит и поможет нам немного, но я продолжу пытаться понять это в то же время и дам вам знать, если я сделаю - person SRMR; 22.10.2015
comment
Вы когда-нибудь в этом разбирались? - person SRMR; 16.02.2016
comment
Нет, я все еще использую свой собственный одноэлементный класс для хранения данных как для приложения для часов, так и для усложнения ... - person Alex; 20.02.2016
comment
Но, как сказал Антониони, использование синглтона кажется допустимым способом - person Alex; 25.06.2016