Showing a progress bar when uploading file to google drive with swift 3 - file-upload

I'm currently developing an application in swift 3 for a school project that requires uploading files to google drive .
The upload is currently working , but i need to inform users with an upload bar.
Here the current code
let folderId: String = folders[indexPath.row].folderId
let metadata = GTLRDrive_File.init()
metadata.name = "Ruin.mp3"
// metadata.mimeType = "application/vnd.google-apps.photo"
metadata.parents = [folderId]
guard let filePath = Bundle.main.path(forResource: "Ruin", ofType: "mp3") else {
return
}
guard let fileData = FileManager.default.contents(atPath: filePath) else {
return
}
let uploadParameters = GTLRUploadParameters(data: fileData , mimeType: "audio/mpeg")
uploadParameters.shouldUploadWithSingleRequest = true
let query = GTLRDriveQuery_FilesCreate.query(withObject: metadata, uploadParameters: uploadParameters)
query.fields = "id"
self.service.executeQuery(query, completionHandler: {(ticket:GTLRServiceTicket, object:Any?, error:Error?) in
if error == nil {
// print("File ID \(files.identifier)")
}
else {
print("An error occurred: \(error)")
}
})
Thanx in advance

Related

How to upload and download Video using QuickBlox in Swift

I am uploading image and video to QuickBlox. My upload is successful but when i download the following scenarios occour:
1) In case of image i am able to download image and show (No issues in this)
2) My question is about video with below points
a) I am able upload video successfully
b) How would i be able to recognize the extension of video from server? I need sample code for uploading and downloading video from the QuickBlox. As if i upload .mov file then what should be the filetype and what should be in case of .mp4 and so on. And when i download the file how would i know the correct extension for the file and then how to get the correct file from the server and save it.
When uploading a video, set the type to "video" in the attachment and the corresponding content type, for example "video/mp4":
QBRequest.uploadFile(with: localVideoUrl, fileName: nameVideo, contentType: "video/mp4", isPublic: true,
successBlock: { (response: QBResponse, uploadedBlob: QBCBlob) -> Void in
let attachment = QBChatAttachment()
attachment.id = uploadedBlob.uid
attachment.name = uploadedBlob.name
attachment.type = "video"
attachment["size"] = "\(uploadedBlob.size)"
// send message with attachment
}, statusBlock: { (request : QBRequest?, status : QBRequestStatus?) -> Void in
let progress = CGFloat(Float(status.percentOfCompletion))
// show progress
}
}) { (response : QBResponse) -> Void in
//error handler
}
When you receive a message with attachment and attachment type is "video”, refer to this example:
let attachment = message.attachments?.first
if attachment.type == "video" {
QBRequest.downloadFile(withUID: attachment.id, successBlock: { (response: QBResponse, fileData: Data) in
let fileData = fileData as NSData
let fileName = ID + "_" + attachment.name
let filePath = NSTemporaryDirectory() + fileName
let fileURL = URL(fileURLWithPath: filePath)
if fileData.write(to: fileURL, atomically: true) == true {
//do what you need with the video - cache, save, play, etc.
} else {
print("failure write")
}
}, statusBlock: { (request: QBRequest, status: QBRequestStatus?) in
let progress = CGFloat(status.percentOfCompletion)
//show progress
}, errorBlock: { (response: QBResponse) in
//error handler
})
}

Download APNG File

I am getting some issues related to APNG file, APNG file animation working perfect if i put APNG files in resource bundle , But when i have download same APNG file from assets server and saving APNG file into resource directory and then load using MSSticker like this way. after loading it showing only first frame.if anyone wanna try to check APNG file please have a look to this.
let imagePath = Bundle.main.path(forResource: imgName, ofType: ".png")
let pathurl = URL(fileURLWithPath: imagePath!)
do {
try cell.stickerview.sticker = MSSticker(contentsOfFileURL: pathurl, localizedDescription: "anything that you want")
}
catch {
fatalError("Failed to create sticker: \(error)")
}
Here i am saving image & getting saved image url from resource directory:
static func saveImage(image: UIImage , name:String) -> Bool? {
guard let data = UIImagePNGRepresentation(image) else {
return false
}
guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) as NSURL else {
return false
}
do {
try data.write(to: directory.appendingPathComponent(name)!)
return true
} catch {
print(error.localizedDescription)
return false
}
}
static func getSavedImageUrl(named: String) -> URL? {
if let dir = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) {
return URL(fileURLWithPath: dir.absoluteString).appendingPathComponent(named)
}
return nil
}
I have written the extension in custom MSSticker class
extension MSStickerView {
func downloadedFrom(url: URL , name: String) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data)
else { return }
DispatchQueue.main.async() { () -> Void in
// self.sticker = image
_ = GameUtil.saveImage(image: image, name: name)
if let pathurl = GameUtil.getSavedImageUrl(named: name) {
do {
try self.sticker = MSSticker(contentsOfFileURL: pathurl, localizedDescription: "Raid")
}
catch {
fatalError("Failed to create sticker: \(error)")
}
}
self.startAnimating()
}
}.resume()
}
func downloadedFrom(link: String , name: String) {
guard let url = URL(string: link) else { return }
downloadedFrom(url: url ,name: name)
}
I think problem is this UIImagePNGRepresentation. Why convert Data to UIImage and then use UIImagePNGRepresentation.
Try saving data directly.
static func saveData(data: Data , name:String) -> Bool? {
guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) as NSURL else {
return false
}
do {
try data.write(to: directory.appendingPathComponent(name)!)
return true
} catch {
print(error.localizedDescription)
return false
}
}
And ignore image just pass data.
_ = GameUtil.saveImage(data: data, name: name)

How to access the media library with Swift code?

I have to display a title of the song which I was selected I get the title(No need to play the song in the music library).What my question is I want to send song I was selected(Encoded) to PHP server..To display the song in a table view from the server and play the song...I want to find the correct path for iTunes music library so that I can encode easily.
func mediaPicker(mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
let documentsUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
do {
// Get the directory contents urls (including subfolders urls)
let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( documentsUrl, includingPropertiesForKeys: nil, options: [])
let mp3Files = directoryContents.filter{ $0.pathExtension == "m4a" }
let mp3FileNames = mp3Files.flatMap({$0.URLByDeletingPathExtension?.lastPathComponent})
} catch let error as NSError {
}
let name = "/aFileName"
var filePath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first
print("\nfilePath: \(filePath)")
filePath = filePath!.stringByAppendingString(name)
print("\nfilePath: \(filePath)")
var filePathURL = NSURL.fileURLWithPath(filePath!)
print("\nfilePathURL: \(filePathURL)")
let item: MPMediaItem = mediaItemCollection.items[0]
print(item)
exportFiles = (item.valueForProperty(MPMediaItemPropertyAssetURL) as? NSURL)!
print(exportFiles)
// Export the ipod library as .m4a file to local directory for remote upload
let exportSession = AVAssetExportSession(asset: AVAsset(URL: exportFiles), presetName: AVAssetExportPresetAppleM4A)
print(exportFiles)
exportSession?.shouldOptimizeForNetworkUse = true
print(exportSession)
playingMusictitle = item.valueForProperty(MPMediaItemPropertyTitle) as? String ?? "Now Playing..."
print("\(exportFiles), title : \(title) ")
let str = exportFiles.absoluteString
let str2 = str!.stringByReplacingOccurrencesOfString("ipod-library://item/item", withString: "")
print(str2)
let arr = str2.componentsSeparatedByString("?")
mimeType = mimeType1.stringByReplacingOccurrencesOfString("id=", withString: "")
let path = item.valueForProperty(MPMediaItemPropertyLyrics) as? String ?? ""
print(path)
exportSession?.outputFileType = AVFileTypeAppleM4A
let documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let format = NSDateFormatter()
format.dateFormat="yyyy-MM-dd-HH-mm-ss"
audioname = "\(playingMusictitle)-\(format.stringFromDate(NSDate())).m4a"
print(audioname)
let documentsDirectoryy = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
self.soundFileURL = documentsDirectoryy.URLByAppendingPathComponent(audioname)
if NSFileManager.defaultManager().fileExistsAtPath(soundFileURL.absoluteString!) {
// probably won't happen. want to do something about it?
print("soundfile \(soundFileURL.absoluteString) exists")
}
Due to copyright protection you can only play songs from music library. You can't access row audio file!.I guess

Uploading Photos Swift/iOS

Sorry for my English I'll do my best.
I have an issue trying to upload photos from the user's library.
First, I get user's photo with this method
func grabPhotos(){
let imgManager = PHImageManager.defaultManager()
let requestOptions = PHImageRequestOptions()
requestOptions.synchronous = false
requestOptions.deliveryMode = .FastFormat
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
if let fetchResult : PHFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: fetchOptions){
if fetchResult.count > 0{
for i in 0..<fetchResult.count{
let asset = fetchResult.objectAtIndex(i) as! PHAsset
if NSComparisonResult.OrderedSame == asset.creationDate!.compare(self.appDelegate.dateLastUpload!){
print("meme date")
}
else if NSComparisonResult.OrderedAscending == asset.creationDate!.compare(self.appDelegate.dateLastUpload!){
}
else {
imgManager.requestImageDataForAsset(asset, options: requestOptions, resultHandler: { (data, string, orientation, objects) in
self.Upload((UIImage(data: data!)?.CGImage)! , nomImage: "\(asset.creationDate)" )
})
}
}
}
else{
print("you got no photos")
}
}
}
as you can see, each time I get a photo I want to upload it to my server.
the upload part works well.
Here is the upload method
func clickUpload(image:CGImage,nomImage : String){
let url = NSURL(string: "http://192.168.1.20:1993/upload")
let image_photo = UIImage(CGImage: image)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
let boundary = generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
if var image_data = UIImageJPEGRepresentation(image_photo,0.8){
let body = NSMutableData()
let fname = nomImage
let mimetype = "image/jpg"
//define the data post parameter
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:multipart/form-data; name=\"test\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("enctype=\"multipart/form-data".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("hi\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"file\"; filename=\"\(fname)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(image_data)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
//request.setValue("multipart/form-data", forHTTPHeaderField: "content-Type")
request.HTTPBody = body
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
task.resume()
}
else {
print(« data nil")
}
}
Now problems come... It works well if I upload photos with reduced size, but I want to upload them in HighQualityFormat.
I got 170 photos on my device, and it uploads approximatively 80 photos before crashing with this message
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSAllocateMemoryPages(1504802) failed'
Could you guys help me to solve it or give me another way to achieve this?
Thank you all.

CloudKit ___recordID is not marked queryable

I tried to save data to the CloudKit programmatically with success but I got an error when I fetch data from CloudKit
I got an error
> <CKError 0x608000052060: "Invalid Arguments" (12/2015); server message
> = "Field '___recordID' is not marked queryable"; uuid = 19F1E556-5384-42FD-8F65-9FD8A9C9523D; container ID =
> "iCloud.com.mywebsite.CloudDemo">
This is my code.
func saveNewRecordTypeToCloud() {
// Prepare the record to save
var record = CKRecord(recordType: "Members")
record.setValue("test", forKey: "name")
record.setValue("test", forKey: "surname")
// Get iCloud Database
let cloudContainer = CKContainer.defaultContainer()
let database = CKContainer.defaultContainer().privateCloudDatabase
// Save the record to iCloud
database.saveRecord(record, completionHandler: { (record:CKRecord!, error:NSError! ) in
if error != nil {
NSLog(error.localizedDescription)
} else {
dispatch_async(dispatch_get_main_queue()) {
println("finished")
}
}
})
}
func getRecordsFromCloud() {
// Fetch data using Convenience API
let cloudContainer = CKContainer.defaultContainer()
let publicDatabase = CKContainer.defaultContainer().privateCloudDatabase
let predicate = NSPredicate(value: true)
let sort = NSSortDescriptor(key: "creationDate", ascending: false)
let query = CKQuery(recordType: "Members", predicate: predicate)
query.sortDescriptors = [sort]
publicDatabase.performQuery(query, inZoneWithID: nil, completionHandler: {
results, error in
if error == nil {
self.members = results as! [CKRecord]
println(self.members)
} else {
println(error)
}
}) }
To resolve such the problem, I had to set the Metadatas Index via Web DashBoard but I want to know if I could set the Metadatas Index by the code?
If so, please give me some code sample.
Thank you for all answers.
Sorry, there is no way to set indexes from code. You have to do this in the CloudKit dashboard.