Swift – Transporte le tableau struct à travers le bloc et récupère les membres

J'ai un bloc d'achèvement qui remet un tableau struct de données à un autre viewcontroller.

Ces données sont reçues dans viewDidLoad comme:

var packArray = [Any]()// the block is returning Any override func viewDidLoad() { super.viewDidLoad() BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self) { (result) in self.packArray = [result] } } 

l'printing de ce self.packArray renvoie le suivant sur une seule ligne et je n'ai maintenant aucune idée de comment je peux extraire datatables.

 [[static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.Ssortingng, 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.Ssortingng, 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.Ssortingng, 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.Ssortingng, 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.Ssortingng, 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.Ssortingng, 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.Ssortingng, 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.Ssortingng, 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.Ssortingng, 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.Ssortingng, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk09", description: "This is some text", title: "Delusion", image: <PFFile: 0x600000241680>, id: "TiLAKBPmaD")]] 

auparavant j'utilisais:

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

mais cela returnne maintenant qu'il n'y a aucun membre packDescription. Je pourrais probablement aller utiliser la gestion de string et créer un désordre mais il doit y avoir une meilleure manière d'get datatables comme tableau réel. Je sais que je le lance comme Any mais je ne pouvais pas find un autre moyen d'get datatables d'un tableau struct à travers un bloc d'achèvement.

—– MODIFIER —-

Dans la class où le tableau est créé, il y a une structure, et array de struct le résultat est passé à travers le completeBlock comme Any

 class func buildArrayFromQuery(queryForCollection: Ssortingng, sender: UIViewController, completeBlock: @escaping (_ result: Any) -> Void) { struct collectionStruct { var name : Ssortingng var description : Ssortingng var title : Ssortingng var image : PFFile var id: Ssortingng } var collectionArray = [collectionStruct]() 

ceci est ensuite créé à partir d'un PFQuery, et le tableau résultant est passé à travers le gestionnaire d'achèvement

 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! Ssortingng let arrayDescription = object.object(forKey: fromDescription) as! Ssortingng let arrayTitle = object.object(forKey: fromTitle) as! Ssortingng let arrayImage = object.object(forKey: fromImage) as! PFFile let arrayID = object.objectId as Ssortingng! collectionArray.append(collectionStruct(name: arrayName, description: arrayDescription, title: arrayTitle, image: arrayImage, id: arrayID!)) } } completeBlock(result: collectionArray) }) 

Vous devez convertir le résultat de la requête au type souhaité. Si vous configurez optionnellement packArray, vous pouvez l'assigner directement en utilisant

 var packArray: [collectionStruct]? self.packArray = result as? [collectionStruct] 

Avec ce code, si le résultat ne peut pas être converti au bon type de tableau, self.packArray contiendra nil.

Ou vous pouvez utiliser une binding facultative:

 var packArray: [collectionStruct] = [] 

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

Vous devez définir packArray en dehors de 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 } } 

Votre code définit une variable locale packArray à l'intérieur de viewDidLoad, ce qui perturbe les choses. Je déconseille d'utiliser une variable d'instance et une variable locale avec le même nom.

Un grand merci à Duncan C pour sa consortingbution, je pense que votre réponse est correcte, je voulais juste partager comment je l'ai modifié pour que cela fonctionne.

Défini la structure en dehors de la class, ce qui me permet d'utiliser [collectionStruct] dans le gestionnaire d'achèvement.

 struct collectionStruct { var name : Ssortingng var description : Ssortingng var title : Ssortingng var image : PFFile var id: Ssortingng } class BuildArray: UICollectionViewController { class func buildArrayFromQuery(queryForCollection: Ssortingng, sender: UIViewController, completeBlock: @escaping (_ result: [collectionStruct]) -> Void) { 

puis returnne le tableau après la requête

 completeBlock(collectionArray) 

puis dans l'autre class comme Duncan C suggéré

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

ceci jette toujours un avertissement:

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

si mal voir ce que je peux faire ici.