Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何在查询函数之外使用解析检索到的对象_Swift_Variables_Object_Parse Platform_Global Variables - Fatal编程技术网

Swift 如何在查询函数之外使用解析检索到的对象

Swift 如何在查询函数之外使用解析检索到的对象,swift,variables,object,parse-platform,global-variables,Swift,Variables,Object,Parse Platform,Global Variables,如何使我的解析数据显示在我想要的地方 我正在制作一个类似Tinder的应用程序,其中我使用parse查询数组,并在一副卡片中显示数据。我有一个查询数组的方法,在同一个方法中,我使用返回的列表。但是我得到一个错误,因为在数据下载完成之前调用了back card。“致命错误:在展开可选值时意外发现nil” 如何处理这个问题,使代码等待检索查询 import UIKit import MDCSwipeToChoose class ChoosePersonViewController: UIViewC

如何使我的解析数据显示在我想要的地方

我正在制作一个类似Tinder的应用程序,其中我使用parse查询数组,并在一副卡片中显示数据。我有一个查询数组的方法,在同一个方法中,我使用返回的列表。但是我得到一个错误,因为在数据下载完成之前调用了back card。“致命错误:在展开可选值时意外发现nil”

如何处理这个问题,使代码等待检索查询

import UIKit
import MDCSwipeToChoose

class ChoosePersonViewController: UIViewController, MDCSwipeToChooseDelegate {

var people:[Person] = []
let ChoosePersonButtonHorizontalPadding:CGFloat = 80.0
let ChoosePersonButtonVerticalPadding:CGFloat = 20.0
var currentPerson:Person!
var frontCardView:ChoosePersonView!
var backCardView:ChoosePersonView!
let nameData = ""

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    let userObjectID = PFUser.currentUser()!.objectId!
    let query = PFQuery(className:"Restaurants")
    query.whereKey("Pointer", equalTo: userObjectID)
    query.findObjectsInBackgroundWithBlock {
        (objects: [PFObject]?, error: NSError?) -> Void in
        if error == nil {
            // The find succeeded.
            print("Successfully retrieved \(objects!.count) scores.")
            // Do something with the found objects
            if let objects = objects {
                for object in objects {
                    var nameData = object.objectForKey("Name") as? String
                    var imageData = object.objectForKey("Image") as? PFFile
                    imageData!.getDataInBackgroundWithBlock { (imageData, error) -> Void in
                        if error == nil {
                            if let imageData = imageData
                            {
                                let image = UIImage(data: imageData)
                                self.people.append(Person(name: nameData, image: image, age: 21, sharedFriends: 3, sharedInterest: 4, photos: 5))
                                print(self.people)
                            }
                        }
                    }
                }
            }
        } else {
            // Log details of the failure
            print("Error: \(error!) \(error!.userInfo)")
        }
    }
    self.people = defaultPeople()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    self.people = defaultPeople()
    // Here you can init your properties
    let imageData: PFFile

}

override func viewDidLoad(){
    super.viewDidLoad()
   // Display the first ChoosePersonView in front. Users can swipe to indicate
    // whether they like or dislike the person displayed.
    self.setMyFrontCardView(self.popPersonViewWithFrame(frontCardViewFrame())!)
    self.view.addSubview(self.frontCardView)

    // Display the second ChoosePersonView in back. This view controller uses
    // the MDCSwipeToChooseDelegate protocol methods to update the front and
    // back views after each user swipe.
    self.backCardView = self.popPersonViewWithFrame(backCardViewFrame())!
    self.view.insertSubview(self.backCardView, belowSubview: self.frontCardView)

    // Add buttons to programmatically swipe the view left or right.
    // See the `nopeFrontCardView` and `likeFrontCardView` methods.
    constructNopeButton()
    constructLikedButton()
}

func suportedInterfaceOrientations() -> UIInterfaceOrientationMask{
    return UIInterfaceOrientationMask.Portrait
}

// This is called when a user didn't fully swipe left or right.
func viewDidCancelSwipe(view: UIView) -> Void{

    print("You couldn't decide on \(self.currentPerson.Name)");
}

// This is called then a user swipes the view fully left or right.
func view(view: UIView, wasChosenWithDirection: MDCSwipeDirection) -> Void{

    // MDCSwipeToChooseView shows "NOPE" on swipes to the left,
    // and "LIKED" on swipes to the right.
    if(wasChosenWithDirection == MDCSwipeDirection.Left){
        print("You noped: \(self.currentPerson.Name)")
    }
    else{

        print("You liked: \(self.currentPerson.Name)")
    }

    // MDCSwipeToChooseView removes the view from the view hierarchy
    // after it is swiped (this behavior can be customized via the
    // MDCSwipeOptions class). Since the front card view is gone, we
    // move the back card to the front, and create a new back card.
    if(self.backCardView != nil){
        self.setMyFrontCardView(self.backCardView)
    }

    backCardView = self.popPersonViewWithFrame(self.backCardViewFrame())
    //if(true){
    // Fade the back card into view.
    if(backCardView != nil){
        self.backCardView.alpha = 0.0
        self.view.insertSubview(self.backCardView, belowSubview: self.frontCardView)
        UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseInOut, animations: {
            self.backCardView.alpha = 1.0
            },completion:nil)
    }
}
func setMyFrontCardView(frontCardView:ChoosePersonView) -> Void{

    // Keep track of the person currently being chosen.
    // Quick and dirty, just for the purposes of this sample app.
    self.frontCardView = frontCardView
    self.currentPerson = frontCardView.person
}

func defaultPeople() -> [Person]{
    // It would be trivial to download these from a web service
    // as needed, but for the purposes of this sample app we'll
    // simply store them in memory.
    return [Person(name: "Finn", image: UIImage(named: "finn"), age: 21, sharedFriends: 3, sharedInterest: 4, photos: 5), Person(name: "Jake", image: UIImage(named: "jake"), age: 21, sharedFriends: 3, sharedInterest: 4, photos: 5), Person(name: "Fiona", image: UIImage(named: "fiona"), age: 21, sharedFriends: 3, sharedInterest: 4, photos: 5), Person(name: "P.Gumball", image: UIImage(named: "prince"), age: 21, sharedFriends: 3, sharedInterest: 4, photos: 5)]


}
func popPersonViewWithFrame(frame:CGRect) -> ChoosePersonView?{
    if(self.people.count == 0){
        return nil;
    }

    // UIView+MDCSwipeToChoose and MDCSwipeToChooseView are heavily customizable.
    // Each take an "options" argument. Here, we specify the view controller as
    // a delegate, and provide a custom callback that moves the back card view
    // based on how far the user has panned the front card view.
    let options:MDCSwipeToChooseViewOptions = MDCSwipeToChooseViewOptions()
    options.delegate = self
    //options.threshold = 160.0
    options.onPan = { state -> Void in
        if(self.backCardView != nil){
            let frame:CGRect = self.frontCardViewFrame()
            self.backCardView.frame = CGRectMake(frame.origin.x, frame.origin.y-(state.thresholdRatio * 10.0), CGRectGetWidth(frame), CGRectGetHeight(frame))
        }
    }

    // Create a personView with the top person in the people array, then pop
    // that person off the stack.

    let personView:ChoosePersonView = ChoosePersonView(frame: frame, person: self.people[0], options: options)
    self.people.removeAtIndex(0)
    return personView

}
func frontCardViewFrame() -> CGRect{
    let horizontalPadding:CGFloat = 20.0
    let topPadding:CGFloat = 60.0
    let bottomPadding:CGFloat = 200.0
    return CGRectMake(horizontalPadding,topPadding,CGRectGetWidth(self.view.frame) - (horizontalPadding * 2), CGRectGetHeight(self.view.frame) - bottomPadding)
}
func backCardViewFrame() ->CGRect{
    let frontFrame:CGRect = frontCardViewFrame()
    return CGRectMake(frontFrame.origin.x, frontFrame.origin.y + 10.0, CGRectGetWidth(frontFrame), CGRectGetHeight(frontFrame))
}
func constructNopeButton() -> Void{
    let button:UIButton =  UIButton(type: UIButtonType.System)
    let image:UIImage = UIImage(named:"nope")!
    button.frame = CGRectMake(ChoosePersonButtonHorizontalPadding, CGRectGetMaxY(self.frontCardView.frame) + ChoosePersonButtonVerticalPadding, image.size.width, image.size.height)
    button.setImage(image, forState: UIControlState.Normal)
    button.tintColor = UIColor(red: 247.0/255.0, green: 91.0/255.0, blue: 37.0/255.0, alpha: 1.0)
    button.addTarget(self, action: "nopeFrontCardView", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)
}

func constructLikedButton() -> Void{
    let button:UIButton = UIButton(type: UIButtonType.System)
    let image:UIImage = UIImage(named:"liked")!
    button.frame = CGRectMake(CGRectGetMaxX(self.view.frame) - image.size.width - ChoosePersonButtonHorizontalPadding, CGRectGetMaxY(self.frontCardView.frame) + ChoosePersonButtonVerticalPadding, image.size.width, image.size.height)
    button.setImage(image, forState:UIControlState.Normal)
    button.tintColor = UIColor(red: 29.0/255.0, green: 245.0/255.0, blue: 106.0/255.0, alpha: 1.0)
    button.addTarget(self, action: "likeFrontCardView", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)

}
func nopeFrontCardView() -> Void{
    self.frontCardView.mdc_swipe(MDCSwipeDirection.Left)
}
func likeFrontCardView() -> Void{
    self.frontCardView.mdc_swipe(MDCSwipeDirection.Right)
}
}

您的var人员现在是一组“人员”

例如,你现在可以说

print(people[index].NumberofPhotos) //will return the number of photos
print(people[index].Name) //will print the person's name

等等。只要你有数组中你想知道的人的索引,这将在代码中的任何地方起作用。

在你的查询中,将你的对象添加到你的人:

for object in objects {
    var nameData = object.objectForKey("Name") as! String                  
    self.people.append(Person(name: nameData, image: nil, age: nil, sharedFriends: nil, sharedInterest: nil, photos: nil))
}

目前,我将名称之外的所有内容都设置为
nil
,因为我不确定您使用哪些键来检索这些内容。但是,总体思路是相同的。

对于objects{..
中的object,继续检索您正在使用的所有属性,然后创建一个Person类,使用
people追加它。在for循环中追加(您的)
。我得到:无法使用类型的索引(UnsafePointer,Int32)为“[Person]”类型的值下标->Unsafemeutablepointer'I get:无法使用类型为“(String,UIImage,Int,Int,Int,Int,Int)”的参数列表调用'append',它表示缺少参数并建议:“self.people.append(Person(姓名:lm,图像:UIImage(名为:“jake”),年龄:21,共享朋友:5,共享兴趣:5,照片:5))”,但生成的变量(如nameData)仍然为空。感谢您坚持我的观点。变量nameData仍然没有使用parse对象进行更新。有什么想法吗?不应该。现在,您正在遍历每个对象。每次,您都在创建一个新变量(nameData)。该变量不会更改。事实上,您可以将其更改为“let”常量;但是,我现在还不担心这个问题。重要的是,对于每个对象,都会向您的人员数组中添加一个新的人员。循环完成后,`print(self.people),您应该有您的人员。在处理它一段时间后,我意识到nameData正在更新。它没有及时更新以使视图显示更新的变量。有没有办法延迟defaultPeople()的请求在下载更新的变量之前?否则我可以将解析后的查询数组作为人员数组返回吗?