Why is the app crashing when I try to append an array? - ios

I am importing an array from parse, and I want to add that array to an array of arrays, but the app crashes when it tries to append the imported array. Why is that occurring and how can I fix it? Crash error is Thread 1: EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0 I commented the append line and it does not crash, so it has to be that line.
var animalarray: [[String]] = []
let query = PFQuery(className: "animals")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil{
for object in objects!{
if let animalss = object["CoordinateTest"]{
print("coord \(animalss)")
self.animalarray.append(animalss as! [String])//crashes here
}
}
}
}

You should create a method that retrieves the data, and use queries to specify what you want. Also you should create a temporary variable to hold to retrieved data and append that variable to the array.
Ex.)
var animalsArray: [String] = []
func retrieveData(){
let query = PFQuery(className: "animals")
query.whereKey("Key", equalTo: object)
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(object:[PFObject]?, error:NSError?) -> Void in
if ( error != nil ){
print(error?.localizedDescription, error?.userInfo)
} else {
for temp: PFObject in object! {
let animals: String = temp["CoordinateTest"] as! String
self.animalsArray.append(animals!)
}
}
}
}

Related

find Parse objects that match Pointer value?

I'm trying to write a Swift query that will get the object in the Avatar table that matches the User's avatar Pointer column. The following query doesn't pull any results:
var userAvatar = self.user["avatar"]
let avatarQuery = PFQuery(className: "Avatar")
avatarQuery.whereKey("objectId", equalTo: userAvatar)
avatarQuery.limit = 1
avatarQuery.findObjectsInBackgroundWithBlock{
(results: [PFObject]?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let results = results as? [PFObject]! {
for result in results {
I think the problem is that the whereKey clauses is looking for a String, yet userAvatar is a PFObject. I tried converting the PFObject to String but that's not possible.
Am I overthinking this? How can I just get the Avatar object that matches the PFObject stored in User -> avatar(Pointer)?
Thanks!
EDIT: Thanks to Daniel, this is the working code (I think adding the includeKey might have helped too):
let userAvatar = self.user["avatar"] as! PFObject
let avatarQuery = PFQuery(className: "Avatar")
avatarQuery.whereKey("objectId", equalTo: userAvatar.objectId!)
avatarQuery.includeKey("avatar")
avatarQuery.limit = 1
avatarQuery.findObjectsInBackgroundWithBlock{
(results: [PFObject]?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let results = results as? [PFObject]! {
for result in results {
So I think your problem is that you should not be comparing a string to a PfObject the object is not a string but a price of the object may be a string so you should compare something like the object.id to a string. If that makes sense.

How to get multiple objects from Parse to save in Local DataStorage in Swift?

I'm getting objects from Parse and display it in my UI. Now I am working on saving the data in Local DataStorage of Parse. I looked at the following Parse example:
let query = PFQuery(className: "GameScore")
query.fromLocalDatastore()
query.getObjectInBackgroundWithId("xWMyZ4YE").continueWithBlock {
(task: BFTask!) -> AnyObject in
if let error = task.error {
// Something went wrong.
return task;
}
// task.result will be your game score
return task;
}
The above example if for fetching 1 object. I dont know how to do the same for multiple objects. I am fetching the objects through MY following code:
let query:PFQuery = PFQuery(className: "Events")
query.findObjectsInBackgroundWithBlock {
(object, error) -> Void in
if object != nil
{
if(object!.count != 0)
{
for messageObject in object! {
let eventName:String? = (messageObject as! PFObject)["EventName"] as? String
let createdBy:String? = (messageObject as! PFObject)["CreatedBy"] as? String
let eventDate:String? = (messageObject as! PFObject)["EventDate"] as? String
objModalClass.eveName = eventName!
objModalClass.crtedBy = createdBy!
objModalClass.eveVenue = eventVenue!
}
}
}
}
In my above code, how can I save all the fetched objects in objModalClass in Local DataStorage. Kindly explain in detail.
You should look object pinning. As long as you have enabled the local datastore, you can retrieve objects by a pin name, as well as releasing those objects from the local datastore with unpinning. From the docs:
"Asynchronously stores the object and every object it points to in the local datastore, recursively."
For single objects:
public func pinInBackgroundWithName(name: String, block:PFBooleanResultBlock?)
For many objects:
public class func pinAllInBackground(objects: [AnyObject]?, withName name: String, block: PFBooleanResultBlock?)
The complementary unpinWithName(name: String) is available for both scenarios. Pinning only works with PFObjects and its subclasses.
You can also query from a pin name like so
var query = PFQuery.queryWithClassname("PFObject_subclass")
query.fromPinWithName("Your_given_pin_name")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
//objects from pin name returned.
}

Parse: PFObject is loaded without Attributes

I need to get some 'Kurse' (PFObjects) from the database and then I need to get the name of another PFObject which is a pointer of the 'kurs' but if I try to do this nothing happens. There is no error and the program does not break or something like that but the "test2" is not printed!
let user = PFUser.currentUser()
let query = PFQuery(className: "Kurs")
query.whereKey("stufe", equalTo: user!["stufe"])
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error != nil {
print(error)
}
else if let kurse = objects{
print("kurse:", kurse)
for kurs in kurse{
print("kurs:", kurs)
var gibtEsSchon = false
if gibtEsSchon == false{
print("test1")
let fach = kurs["fach"] as! PFObject
print("fach", fach)
let name = fach["name"] as! String
print("test2")
self.daten.append(Fach(dieKurse: [kurs], name: name))
print("daten 3", self.daten)
}
}
}
So the line
let name = fach["name"] as! String
is not called.
But I think I know why: If I print("fach", fach) the result doesn't have the attribute 'name' that it should have. I think that the PFObject is not loaded completely:
What I get:
fach {
}
What I want:
fach {
name = German;
}
Adding query.includeKey("fach") above query.findObjectsInBackgroundWithBlock should fix that.
From the PFQuery class reference, includeKey will
Make the query include PFObjects that have a reference stored at the provided key.

Unable to retrieve createdAt values from Parse objects

I cannot get the createdAt value from Parse for each object.And I dont want to have to save an additional timestamp as a String when the data is sitting right there.
This is the list of what i was doing.I hope someone who can help
----------------------------------------------------------------------
var followArray = [String]()
var resultsNameArray = [String]()
var resultsIcon = [PFFile]()
var resultsImgArray = [PFFile?]()
var resultsTimeTampArray = [NSDate?]()
-------------------------------------------------------------------
func refreshResult()
{
var followQuery = PFQuery(className: "Follow")
followQuery.whereKey("user", equalTo: PFUser.currentUser()!.username!)
followQuery.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil
{
for object in objects!
{ self.followArray.append(object.objectForKey("Following") as! String)
}
var query = PFQuery(className: "Moments")
query.whereKey("userName", containedIn: self.followArray)
query.addDescendingOrder("createdAt")
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil
{
for object in objects!
{
self.resultsNameArray.append(object.objectForKey("profileName") as! String)
self.resultsIcon.append(object.objectForKey("icon") as! PFFile)
self.resultsImgArray.append(object.objectForKey("image") as? PFFile)
//tried to use "createdAt" property but it i still getting nil value from Parse
self.resultsTimeTampArray.append(object.objectForKey("createdAt") as! NSDate)
}
//reload table
self.resultsTable.reloadData()
}
}
}
}
-----------------------------------------------------------------------
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:TimelineCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! TimelineCell
enter code here //I'v got an error here!
//fatal error: unexpectedly found nil while unwrapping an Optional value
// dataFormatter
var dateFormatter:NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
var strDate = dateFormatter.stringFromDate(self.resultsTimeTampArray[indexPath.row]!)
return cell
}
Don't access it using objectForKey, just access it directly via the createdAt property.
As explicitly stated in the docs, the keys:
This does not include createdAt, updatedAt, authData, or objectId. It does include things like username and ACL.
You can access it directly in your for object loop like this.
object.updatedAt
instead of
objectforkey("updatedAt")

Getting data from Parse with findObjectsInBackgroundWithBlock

I'm using Parse findObjectsInBackgroundWithBlock that returns [AnyObject]? how do I extract the column data?
You need to cast your results like so:
objects as? [PFObject], then each result will contain a PFObject dictionary with the column name as the key. for example o["id"] will return the value of the id column for a specific object
Just do
let data = objects as! [PFObject]
let firstObject = objects[0]
// firstObject["Column"]
Well it is easy like the code below,
In my case i get the score you can use your DB table column names
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects as? [PFObject] {
for object in objects {
var score : Int? = object["score"] as! Int?
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}

Resources