2017-01-02 2 views
0

У меня есть блок завершения, который передает массив структур данных другому диспетчеру просмотра.Swift - передать массив структур через блок и получить члены

Эти данные получены в viewDidLoad как:

var packArray = [Any]()// the block is returning Any 

    override func viewDidLoad() { 
     super.viewDidLoad() 
      BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self) { (result) in  
        self.packArray = [result] 
      } 
    } 

печати этот self.packArray возвращает следующий все в одной строке, и я в настоящее время не имеют ни малейшего представления о том, как я могу извлечь данные.

[[static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk00", description: "This is some text", title: "Not a murderer", image: <PFFile: 0x60000005fc80>, id: "rHITAAHJYk"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk01", description: "This is some text", title: "Addiction", image: <PFFile: 0x600000240300>, id: "uGHHpPF89e"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk02", description: "This is some text", title: "Towels are noisy", image: <PFFile: 0x600000240570>, id: "PeM7hJ4sih"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk03", description: "This is some text", title: "Class action", image: <PFFile: 0x6000002407e0>, id: "LoSXT2PFoS"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk04", description: "This is some text", title: "Beer", image: <PFFile: 0x600000240a50>, id: "vxEsd13twt"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk05", description: "This is some text", title: "Not again...", image: <PFFile: 0x600000240cc0>, id: "JNqaAgtdRb"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk06", description: "This is some text", title: "Foreign cars", image: <PFFile: 0x600000240f30>, id: "Hb16TDXGbz"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk07", description: "This is some text", title: "Skin problems", image: <PFFile: 0x6000002411a0>, id: "MUYDMnJCrU"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk08", description: "This is some text", title: "Junk food", image: <PFFile: 0x600000241410>, id: "yowAfJlcmr"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) ->()) ->()).(collectionStruct #1)(name: "pk09", description: "This is some text", title: "Delusion", image: <PFFile: 0x600000241680>, id: "TiLAKBPmaD")]] 

ранее я использовал:

cell.labelCell.text = self.packArray[indexPath.item].packDescription 

но теперь возвращается, что нет ни одного члена packDescription. Я, вероятно, могу пойти и использовать обработку строк и создать беспорядок, но должен быть лучший способ получить данные как фактический массив. я знаю, что я использую его как Any, но не смог найти другого способа получить данные из массива struct через блок завершения.

----- EDIT ----

В классе, где массив создается есть структура, и массив из структуры результат передается через completeBlock в любой

class func buildArrayFromQuery(queryForCollection: String, 
     sender: UIViewController, 
     completeBlock: @escaping (_ result: Any) -> Void) { 

    struct collectionStruct { 
     var name : String 
     var description : String 
     var title : String 
     var image : PFFile 
     var id: String 
    } 

     var collectionArray = [collectionStruct]() 

это то создается из PFQuery, и полученный массив проходит обратно через обработчик завершения

query.findObjectsInBackground(block: { (objects, error) in 

if error != nil { 
    print(error!) 

} else if let packs = objects { 


    for object in packs { 

     print(fromName) 

     print(object) 

     let arrayName = object.object(forKey: fromName) as! String 
     let arrayDescription = object.object(forKey: fromDescription) as! String 
     let arrayTitle = object.object(forKey: fromTitle) as! String 
     let arrayImage = object.object(forKey: fromImage) as! PFFile 
     let arrayID = object.objectId as String! 

     collectionArray.append(collectionStruct(name: arrayName, description: arrayDescription, title: arrayTitle, image: arrayImage, id: arrayID!)) 
    } 

} 


completeBlock(result: collectionArray) 

}) 
+0

Вы не предоставили достаточную информацию. Какой тип объекта содержит массив? –

+0

Извинения, PFFile и String. я отредактирую сообщение с еще ... – Pippo

ответ

1

Вы должны привести результат запроса к желаемого типа. Если вы сделаете packArray необязательным, вы можете назначить его непосредственно с помощью

var packArray: [collectionStruct]? 

self.packArray = result as? [collectionStruct] 

С этим кодом, если результат не может быть приведен к нужному типу массива, self.packArray будет содержать ноль.

Или вы можете использовать опциональное связывание:

var packArray: [collectionStruct] = [] 

...

if structsArray = result as [collectionStruct] { 
    self.packArray = structsArray 
} 

Вы должны определить packArray вне viewDidLoad:

var packArray: [collectionStruct] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 
    BuildArray.buildArrayFromQuery(queryForCollection: "Pack", 
    sender: self) { 
     (result) in 
     if structsArray = result as [collectionStruct] { 
     self.packArray = structsArray 
    } 
} 

Вашего код определяет локальный переменный packArray внутри viewDidLoad, что путает вещи. Я рекомендую использовать переменную экземпляра и локальную переменную с тем же именем.

+0

Спасибо, что похоже, что он должен работать. Есть еще небольшая проблема, поскольку блок завершения возвращается (_ Результат: (Любой) он возвращает «Любой не конвертируется в. ..collectionStruct ", поскольку collectionstruct не является типом i, не думаю, что он может быть передан через обработчик завершения. – Pippo

+0

также как collectionStruct определяется в классе, где выполняется блок завершения. В этом классе, где мы устанавливаем packArray, нет коллекцииStruct – Pippo

+0

У вас есть (или требуется) инициализатор для 'struct'? – Adrian

0

Большое спасибо Duncan C за его вклад, плохо отметите ваш ответ как правильный, я просто хотел поделиться тем, как я подстроил его, чтобы заставить его работать.

Определяет структуру вне класса, которая позволяет мне использовать [collectionStruct] в обработчике завершения.

struct collectionStruct { 
    var name : String 
    var description : String 
    var title : String 
    var image : PFFile 
    var id: String 
} 

class BuildArray: UICollectionViewController { 

    class func buildArrayFromQuery(queryForCollection: String, 
        sender: UIViewController, 
        completeBlock: @escaping (_ result: [collectionStruct]) -> Void) { 

затем возвращают массив после запроса

completeBlock(collectionArray) 

, а затем в другом классе, как Дункан C предложил

if let structsArray = result as? [collectionStruct] { 
    self.packArray = structsArray 
} 

это еще trows предупреждение:

"non option expression type [collectionStruct] used in check for optionals" 

так плохо видеть, что я могу сделать Вот.