2016-05-03 3 views
1

Вот мой код ниже:Swift: Попытка извлечь данные из DataSource Struct

class DataSource: NSObject { 
    var categories = [String]() 
    var items = [Item]() 

    private override init() { 
     super.init() 
    } 

    class var sharedDataSource: DataSource { 
     struct Static { 
      static var onceToken: dispatch_once_t = 0 
      static var instance: DataSource! 
     } 
     dispatch_once(&Static.onceToken) { 
      let dataSource = DataSource() 
      Static.instance = dataSource 

      let urlPath = "myUrlPathString" 
      let endpoint = NSURL(string: urlPath) 
      let request = NSMutableURLRequest(URL: endpoint!) 

      NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: { (data, response, error) in 
       let json = JSON(data: data!) 
       print(json) 
       for obj in json.arrayValue { 
        let item: Item = Item() 
        item.itemID = obj["item"].stringValue 
        item.price = obj["price"].floatValue 
        item.title = obj["title"].stringValue 
        item.category = obj["category"].stringValue 
        item.available = obj["available"].boolValue 
        item.image = obj["image"].stringValue 
        print(item.title) 
        dataSource.items.append(item) 
        print(dataSource.items) 
        print("STOP") 
       } 
      }).resume() 
     } 
     return Static.instance 
    } 
} 

Я пытаюсь использовать результат этого DataSource в UICollectionView, назначив его результат в массив Item. Я успешно захватываю данные в моем NSURLSession, и его локальный список «элементы» заполняется.

В моей UICollectionView, в моем viewDidLoad, я назначаю свою локальную переменную следующим образом:

let dataSource = DataSource() 
items = dataSource.sharedInstance.items 

Печать значение в viewDidLoad всегда приводит к пустой массив без каких-либо значений, но я знаю, что значения там к моменту окончания NURLSession. Я не уверен, как написать для этого обработчик завершения. Это мой первый раз, когда я делаю подобные вещи с sharedDataSource, который является структурой.

Любые идеи кто-нибудь?

Спасибо,

Шон

ответ

0

Если вы делаете это в viewDidLoad то, скорее всего, сессия NSURL не завершена к тому времени, вы пытаетесь получить массив элементов. Отправьте уведомление в свой класс dataSource после того, как данные были получены, а затем установите элементы.

Например

NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: { (data, response, error) in 
      let json = JSON(data: data!) 
      print(json) 
      for obj in json.arrayValue { 
       let item: Item = Item() 
       item.itemID = obj["item"].stringValue 
       item.price = obj["price"].floatValue 
       item.title = obj["title"].stringValue 
       item.category = obj["category"].stringValue 
       item.available = obj["available"].boolValue 
       item.image = obj["image"].stringValue 
       print(item.title) 
       dataSource.items.append(item) 
       print(dataSource.items) 
       print("STOP") 
      } 
      NSNotificationCenter.defaultCenter().postNotificationName("dataRecievedNotification", object: nil) 

     }).resume() 

Но вы также должны быть в состоянии получить это уведомление в вашем ViewController с CollectionView. Таким образом, в viewDidLoad добавить

NSNotificationCenter.defaultCenter().addObserver(self, selector: "dataRecieved", name: "dataRecievedNotification", object: nil) 

Затем добавить функцию в том же ViewController:

func dataRecieved() { 
    print("data received") 
    items = dataSource.sharedInstance.items 
    collectionView.reloadData() 
} 

Где DATASOURCE переменная объявлена ​​выше viewDidLoad:

let dataSource = DataSource() 

Не забывайте, что если вы используют наблюдателей, которые вам нужно удалить, когда класс удаляется из памяти, поэтому в ViewController добавьте эту функцию deinit:

deinit { 
    NSNotificationCenter.defaultCenter().removeObserver(self) 
} 

EDIT: Я думаю, что ваш одноэлементный шаблон можно упростить, используя современный быстрый. Вам больше не нужно использовать struct или dispatch_once, просто объявив, что статический let shared instance будет обрабатывать все это для вас. Имея это в виду, я пытался упростить свой класс DataSource:

class DataSource { 

static let sharedInstance = DataSource() 

var items = [Item]() 

private init() {} 

func retrieveItems() { 

    let urlPath = "myUrlPathString" 
    let endpoint = NSURL(string: urlPath) 
    let request = NSMutableURLRequest(URL: endpoint!) 

    NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: { (data, response, error) in 

     let json = JSON(data: data!) 
     print(json) 

     for obj in json.arrayValue { 
      let item: Item = Item() 
      item.itemID = obj["item"].stringValue 
      item.price = obj["price"].floatValue 
      item.title = obj["title"].stringValue 
      item.category = obj["category"].stringValue 
      item.available = obj["available"].boolValue 
      item.image = obj["image"].stringValue 
      print(item.title) 
      items.append(item) 
      print(items) 
      print("STOP") 
     } 

     NSNotificationCenter.defaultCenter().postNotificationName("dataRecievedNotification", object: nil) 

    }).resume() 

} 

} 

, где вы, в viewDidLoad, добавьте следующую логику:

if DataSource.sharedInstance.items.count == 0 { 
    DataSource.sharedInstance.retrieveItems() 
} 

затем изменить dataRecieved к

func dataRecieved() { 
    print("data received") 
    items = DataSource.sharedInstance.items //Notice the capital 
    collectionView.reloadData() 
} 

и удалите объявление var dataSource = DataSource() выше viewDidLoad

+0

Я пробовал код выше.Кажется, что все происходит в правильном порядке, но мой массив по-прежнему пуст после завершения сеанса NSURL и запускается функция dataReceived, элементы по-прежнему остаются пустым массивом в моем UICollectionView по какой-то причине. Хмм. Я также не могу: let dataSource = DataSource() Если я не установил инициализатор публично. Но тогда элементы = dataSource.sharedInstaince.items не будут работать. Это должны быть элементы = dataSource.items, и это вообще не вызывает NSURLSession. :( Hrm. – Pleirosei

+0

Я изменил ваш dataSource класс, пожалуйста, сообщите мне, если это не имеет смысла/все еще не работает :) –

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