Can't retrieve a picture to swift from parse.com using their documentation - ios

I have been trying to follow parse.com's intruction to retrieve a picture I already successfully uploaded (also using their documentation). My code:
let testObject = PFObject(className: "TestObject")
let file = testObject["SampleImage.png"] as PFFile
file.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let image = UIImage(data:imageData)
self.mainImg.image = image
print("Image Retreived")
I am getting the error:
"AnyObject! is not convertible to 'PFFile'"
and then it sugests that I include a ! in 'as'. However, when I do, the application runs but does not retrieve anything.
I realize this question is posted elsewhere, but the answer is not working for me. What am I doing wrong?

let testObject = PFObject(className: "TestObject")
This is a new empty object which isn't backed by anything on the server. You need to set the id to a known value and refresh the instance of you need to run a query to find an object before the resulting object will contain anything.

Related

Swift Get data from Firebase Storage

I'm trying to fetch image data from firebase storage with swift .
Code :
let ref = Storage.storage().reference().child("users").child("uid").child("savedimage");
let task = ref.getData(maxSize: 1024*1024*12) { (data, error) in
if let data = data , let image = UIImage(data: data) {
print("image exists");
self.imageView.image = image;
}else {
print(error);
}
}
task.resume();
But most of the time the app crash after a second of getting the image , and take me to this :
It's not showing any error in console output so i cannot figure out what's the issue but sometimes it's give me a warning before the crash :
warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.
What i'm doing wrong ?

aws dynamodb how to use object mapper with batch get in ios swift

Thanks in advance for any help. I am trying to get Batch items (Load multiple) items from one DynamoDb table using the AWS iOS SDK (Swift). I can load one item using the Block syntax, but I need to load 10 or more than that. I don't want to use 10 Block calls to load them individually. I tried to follow the attach stackoverflow Link (where the similar solution is given) but I am getting the following compiler error message. I come from Java background, hence could also be a syntax issue. Is it the right way to load multiple items? I don't want to use low level API. Any help, where I am going wrong. Thanks.
aws dynamodb how to use object mapper with batch get in ios
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
var tasksList = Array<AWSTask<AnyObject>>()
for i in 1...10 {
tasksList.append(dynamoDBObjectMapper.load(AWSCards.self, hashKey: "SH_"+String(i), rangeKey: nil))
}
AWSTask.init(forCompletionOfAllTasksWithResults: tasksList).continueWithBlock { (task) -> AnyObject? in
if let cards = task.result as? [AWSCards] {
print(cards.count)
}
else if let error = task.error {
print(error.localizedDescription)
}
return nil
}
Have a try with the following codes (Swift 4.1, Feb 9th, 2018):
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
var tasksList = Array<AWSTask<AnyObject>>()
for i in 1...10 {
tasksList.append(dynamoDBObjectMapper.load(AWSCards.self, hashKey: "SH_"+String(i), rangeKey: nil))
}
AWSTask<AnyObject>.init(forCompletionOfAllTasksWithResults: tasksList).continueWith { (task) -> Any? in
if let cards = task.result as? [AWSCards] {
print(cards.count)
}
else if let error = task.error {
print(error.localizedDescription)
}
return nil
}
Your question is "how to use the object mapper" but it might be more efficient for you to not use it.
However, there is a way to use it. See Niklas's answer here and here (he copy & pasted), but something about it strikes me as fishy. I want to make the assertion that it is not as fast as the built-in batch-get function, but I am unsure. I suspect that this does not complete the items in parallel, or at least not as efficiently as in BatchGetItem.
See the docs: "In order to minimize response latency, BatchGetItem retrieves items in parallel."
According to Yosuke, "Currently, AWSDynamoDBObjectMapper does not support the batch get item. You need to load one item at a time if you want to use the object mapper" as of 2016. This still seems to be the case. I am using a version a couple versions behind, but not too far behind. Someone check.
In conclusion, if you are loading one item at a time, you are likely missing out on the whole purpose of BatchGetItem (low latency).
Pulling from various sources, including John Davis's question here, I have tested and ran this BatchGetItem result. Here ya go.
import AWSDynamoDB
let primaryKeyToSortKeyDict : [String : String] = .... // Your stuff
var keys = [Any]()
for key in primaryKeyToSortKeyDict.keys {
let partitionKeyValue = AWSDynamoDBAttributeValue()
partitionKeyValue?.s = String(key)
let sortValue = AWSDynamoDBAttributeValue()
sortValue?.s = String(primaryKeyToSortKeyDict[key]!)
keys.append(["partitionKeyAttributeName": partitionKeyValue, "sortKeyAttributeName": sortValue])
}
let keysAndAttributesMap = AWSDynamoDBKeysAndAttributes()
keysAndAttributesMap?.keys = keys as? [[String : AWSDynamoDBAttributeValue]]
keysAndAttributesMap?.consistentRead = true
let tableMap = [table : keysAndAttributesMap]
let request = AWSDynamoDBBatchGetItemInput()
request?.requestItems = tableMap as? [String : AWSDynamoDBKeysAndAttributes]
request?.returnConsumedCapacity = AWSDynamoDBReturnConsumedCapacity.total
guard request != nil else {
print("Handle some error")
return
}
AWSDynamoDB.default().batchGetItem(request!) { (output, error) in
print("Here is the batchgetitem output")
if error == nil {
// do output stuff
} else {
// handle error
}
}

Store Parse Files to Amazon S3 using iOS Swift XCode

I have hosted my own Parse Server on Heroku. I am adding files to a Parse table column and want to save to my own S3,
I have followed the guide,
https://github.com/ParsePlatform/parse-server/wiki/Storing-Files-in-AWS-S3
I created my own bucket, created my user, created my policy, attached my policy to my user
Edited my Parse server deployment on Heroku to point to a new filesAdapter
But the following code is still saving the file to MongoDB(GridStore), is there anything else needed to be done to start using my own S3?
let myImage : UIImage = UIImage(named:"bird")!
let imageData: NSData = UIImagePNGRepresentation(myImage)!
let imageFile: PFFile = PFFile(name: "bird.png", data: imageData)!
let pfuser = PFObject(className: "TestObject")
pfuser.setObject("sample text", forKey: "textcol")
pfuser.setObject(imageFile, forKey: "image")
pfuser.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
print("Object has been saved.")
}
Thank you!

Does parse PFUser download all User object columns content?

I have a User class in Parse that contains a profilePicture along with some other User info. I couldn't figure out if when I run a query in Swift and Parse returns the PFUser object, does that object already contain the profilePicture or does it download it when I use
PFUser.currentUser()?["profilePicture"]
The object only contain the profilePicture as a PFFile (PFFile representes a file of binary data stored on the Parse servers). You are simply accessing the PFFile which is by indexing with ["profilePicture"].
To get the actual profilePicture when you use it, you can do something like the following to turn the PFFile into UIImage and display it out.
let imageFile = listingObjectPassed["imageFile"] as! PFFile
imageFile.getDataInBackgroundWithBlock { (data, error) -> Void in
if let downloadedImage = UIImage(data: data!) {
self.imagePic.image = downloadedImage
}
}

Retrieving Parse Images Are Out of Order Swift

I am writing an application in Swift that uses Parse for its backend. The user can post images to parse and they are displayed in a collectionView when the user logs in.
The new problem I am having is when retrieving all of my images from parse for the current user, the images are displayed all out of order. Actually, just about every time the images are retrieved they are in a slightly different order. I tried looking at other posts where people had this problem but they didn't seem to do the trick.
Here is my code to retrieve all image posts by a user (the current user):
func retrieveAllImagesForUserId(userId:String){
self.arrayOfUserPosts.removeAll()
let query = PFQuery(className: "ImagePost")
query.whereKey("UserId", equalTo: userId)
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 username: String = temp["Username"] as! String
let userId: String = temp["UserId"] as! String
let description: String = temp["ImageDescription"] as! String
let imageId: String = temp.objectId!
let file: PFFile = temp["Image"] as! PFFile
file.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let retrievedImage = UIImage(data: imageData)
self.imagePost = ImagePost.init(
image: retrievedImage!,
userId: userId,
imageId: imageId,
description: description,
username: username)
self.arrayOfUserPosts.append(self.imagePost!)
NSNotificationCenter.defaultCenter().postNotificationName("retrievedPost", object: nil)
}
}
}
}
}
}
}
The first thing i did was remove all objects to avoid any possible duplications to occur, maybe from a previous user who was logged on to the same device or anything like that.
For every image posted, i am also posting a column which has the users objectId whom posted that image. This way, i can query where said key is equal to the current users objectId.
I am doing an additional query to orderByDescending("createdAt") so the new images will be displayed at the top of my collection view.
My ImagePost class is an extremely simple class that is used for populating the area with objects, it looks like this:
class ImagePost {
var postedImage: UIImage?
var userId: String?
var imageId: String?
var description: String?
var username: String?
init(image:UIImage, userId:String, imageId:String, description: String, username: String ) {
self.postedImage = image
self.userId = userId
self.imageId = imageId
self.description = description
self.username = username
}
}
When the data is retrieved, i append the new ImagePost object to my array, which is the array i used to populate my collectionView and send a notification to reload the collection view.
I just really don't understand why I am having this problem so all of a sudden where the images are being retrieved in almost any order they choose. Any help would be greatly appreciated.
If you know the solution in objective-c but not swift that will also be helpful.
Thank you,
Rob
I had integrated something similar using Parse.
You don't need to fetch all the images at first. You can use a third party library SDWebImageCache for downloading the image when needed or caching.
Have the postedImage type as PFFile and assign the imageFile directly. No need of fetching the imageData.
Have another key called updatedAt in ImagePost class. No need of using predicate when querying the objects from Parse. Save the updatedAt time of ImagePost class. So now you can directly append the data to arrayOfUserPosts.
After completion of the loop, you can sort the array and assign it to self.arrayOfUserPosts.
Then in tableView's dataSource tableView:cellForRowAtIndexPath: method, you can do something like,
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:file.url] placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// Any custom view initialisation if needed.
}
where imageView is your display view for image, file is the object of type PFFile which represent the image. This is a Objective-C code. Similar syntax for Swift.

Resources