Store Parse Files to Amazon S3 using iOS Swift XCode - ios

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!

Related

Process for uploading image to s3 with AWS Appsync || iOS image uploading with Appsync

I'm working on a new project that requires uploading attachments in the form of images. I'm using DynamoDB and AppSync API's to insert and retrieve data from database. As we are new to the AppSync and all the amazon services and database we are using for the app i'm little bit confused about the authentication process. Right now we are using API key for authentication and I have tried these steps to upload image to s3.
1 Configue the AWSServiceManager with static configuration like :-
let staticCredit = AWSStaticCredentialsProvider(accessKey: kAppSyncAccessKey, secretKey: kAppSyncSecretKey)
let AppSyncRegion: AWSRegionType = .USEast2
let config = AWSServiceConfiguration(region: AppSyncRegion, credentialsProvider: staticCredit)
AWSServiceManager.default().defaultServiceConfiguration = config
2 Uploading picture with this method : -
func updatePictureToServer(url:URL, completion:#escaping (Bool)->Void){
let transferManager = AWSS3TransferManager.default()
let uploadingFileURL = url
let uploadRequest = AWSS3TransferManagerUploadRequest()
let userBucket = String(format: "BUCKET")
uploadRequest?.bucket = userBucket
let fileName = String(format: "%#%#", AppSettings.getUserId(),".jpg")
uploadRequest?.key = fileName
uploadRequest?.body = uploadingFileURL
transferManager.upload(uploadRequest!).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
if let error = task.error as NSError? {
if error.domain == AWSS3TransferManagerErrorDomain, let code = AWSS3TransferManagerErrorType(rawValue: error.code) {
switch code {
case .cancelled, .paused:
break
default:
print("Error uploading: \(String(describing: uploadRequest!.key)) Error: \(error)")
}
} else {
print("Error uploading: \(String(describing: uploadRequest!.key)) Error: \(error)")
}
completion(false)
return nil
}
_ = task.result
completion(true)
print("Upload complete for: \(String(describing: uploadRequest!.key))")
return nil
})
}
3 And finally i'm able to see the uploaded image on the S3 bucket
But i'm concerned about how to save the url of the image and how to retrieve the image because when i have to make the buket PUBLIC to retrieve the image and i don't think that's a good approach, plus is it necessary to have a Cognito user pool because we aren't using Cognito user pool yet in our app and not have much knowledge about that too and documents are not helping in practical situations because we are implementing ti for the first time so we need some little help.
So two question : -
Proper procedure to use for uploading and retrieving images for S3 and AppSync.
Is it necessary to use Cognito user pool for image uploading and retrieving.
Thanks
Note: Any suggestion or improvement or anything related to the AppSync, S3 or DynamoDB will be truly appreciated and language is not a barrier just looking for directions so swift or objective-c no problem.
You need per-identity security on the bucket using Cognito Federated Identities which gives each user their own secure bucket. You can leverage the AWS Amplify to set this up for your project with $amplify add auth and selecting the default config, then $amplify add storage which configures that bucket and pool with appropriate permissions to use private uploads.
For more info checkout the repo: https://github.com/aws-amplify/amplify-cli

How to upload a video from iOS photo album to Azure Blob Storage

I am struggling with uploading videos from iOS photo album to Azure blob storage. I am using AZSClient.
uploading images is straight forward, ie. I get the image 'Data' from PHAsset and then upload it to azure storage using AZSCloudBlockBlob.uploadFromData method
Can anyone guide me on how to upload a video to azure blob preferably in swift
There was a similar thread for this they used the bellow code, and they used the IOS library found here:
//Upload to Azure Blob Storage with help of SAS
func uploadBlobSAS(container: String, sas: String, blockname: String, fromfile: String ){
// If using a SAS token, fill it in here. If using Shared Key access, comment out the following line.
var containerURL = "https://yourblobstorage.blob.core.windows.net/\(container)\(sas)" //here we have to append sas string: + sas
print("containerURL with SAS: \(containerURL) ")
var container : AZSCloudBlobContainer
var error: NSError?
container = AZSCloudBlobContainer(url: NSURL(string: containerURL)! as URL, error: &error)
if ((error) != nil) {
print("Error in creating blob container object. Error code = %ld, error domain = %#, error userinfo = %#", error!.code, error!.domain, error!.userInfo);
}
else {
let blob = container.blockBlobReference(fromName: blockname)
blob.uploadFromFile(withPath: fromfile, completionHandler: {(NSError) -> Void in
NSLog("Ok, uploaded !")
})
}
}
I found the answer in this thread
let manager = PHImageManager.default()
manager.requestAVAsset(forVideo: asset, options: nil, resultHandler: { (avasset, audio, info) in
if let avassetURL = avasset as? AVURLAsset {
guard let video = try? Data(contentsOf: avassetURL.url) else {
return
}
videoData = video
}
})
once you get the Data object then you can use AZSCloudBlockBlob.uploadFromData to upload it to azure storage

Swift 3 Azure Blob Storage Data (Image, Video) upload with SAS

I'm searching for an useful Swift 3 Azure Blob Storage example which I could use to upload some data(image, video). For now, I can insert records into my Mobile Service database and there I generate a SAS and I get it back to my iOS application. Now I need to know how to upload to Azure Blob Storage with help of that SAS. I successfully implemented the same for Android and it works, but somehow I have troubles to find any useful information for "SWIFT" and how to use the "SAS"!
Any code examples how to upload with SAS in Swift are much appreciated.
Regards,
Adam
For those who have the same problem as I had: This is a working example in Xcode 8 and Swift 3. You have to include the "Azure Storage Client Library" into your project.
//Upload to Azure Blob Storage with help of SAS
func uploadBlobSAS(container: String, sas: String, blockname: String, fromfile: String ){
// If using a SAS token, fill it in here. If using Shared Key access, comment out the following line.
var containerURL = "https://yourblobstorage.blob.core.windows.net/\(container)\(sas)" //here we have to append sas string: + sas
print("containerURL with SAS: \(containerURL) ")
var container : AZSCloudBlobContainer
var error: NSError?
container = AZSCloudBlobContainer(url: NSURL(string: containerURL)! as URL, error: &error)
if ((error) != nil) {
print("Error in creating blob container object. Error code = %ld, error domain = %#, error userinfo = %#", error!.code, error!.domain, error!.userInfo);
}
else {
let blob = container.blockBlobReference(fromName: blockname)
blob.uploadFromFile(withPath: fromfile, completionHandler: {(NSError) -> Void in
NSLog("Ok, uploaded !")
})
}
}

Download and use files stored in Firebase Storage from different projects

I'm using Firebase Storage to store images in FB, I'm saving download URL in Realtime DB and to retrieve some photos from the storage, I'm using this code:
let storage = FIRStorage.storage()
imageRefInDB.observeEventType(.Value, withBlock: { (snapshot) in
// Get download URL from snapshot
let downloadURL = snapshot.value as! String
// Create a storage reference from the URL
let storageRef = storage.referenceForURL(downloadURL)
storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
print(error.debugDescription)
} else {
let downloadedImage = UIImage(data: data!)
}
}
})
My problem is I wanna use some of my photo that are inside another Firebase project. For example, the download URLs will be:
https://firebasestorage.googleapis.com/v0/b/PROJECT1.appspot.com/o/someMedia&token
When in my current project, the bucket is different like :
https://firebasestorage.googleapis.com/v0/b/PROJECT2.appspot.com/o/someMedia&Token
When I try to using the PROJECT1 files in my current PROJECT2, I'm getting the following error:
reason: 'Provided bucket: PROJECT1.appspot.com does not match bucket specified in FIRApp configuration: PROJECT2.appspot.com
Is there a way to enable downloading theses files from other projects like a setting in Firebase without retrieving them with regular URL downloads?
Thanks for your help!
I tried that once and it lead to an unhappy time. In my case I had two different buckets for my images, so I had to find an alternate solution.
If you have only a single bucket, you can try configuring that bucket in your FIRApp:
let firOptions = FIROptions(googleAppID: googleAppID, bundleID: bundleID, GCMSenderID: GCMSenderID, APIKey: nil, clientID: nil, trackingID: nil, androidClientID: nil, databaseURL: databaseURL, storageBucket: storageBucket, deepLinkURLScheme: nil)
FIRApp.configureWithName("anotherClient", options: options)
let app = FIRApp(named: "anotherClient")
let storageRef = FIRStorage.storage(app: app!).reference()
Taken from this answer, so you may need to modify it to suit your needs
With that app, you can then use the Firebase Storage API as you're already doing to download the image data.
If you have multiple buckets (as I had), you either have to configure multiple apps or (as I did) handle downloading the image from the downloadURL yourself (without using the Firebase Storage API):
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) {
let data = NSData(contentsOfURL: downloadURL) //make sure your image in this url does exist, otherwise unwrap in a if let check
dispatch_async(dispatch_get_main_queue(), {
let downloadedImage = UIImage(data: data!)
});
}

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

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.

Resources