I am attempting to transfer an image downloaded from facebook but for some reason my transferFile method has stopped working. The same code seemed to be working an hour ago and I cannot find what I have changed in order to cause it to stop working.
I am not getting an error from the delegate method nor is my log being called on the watch's side.
Here is how I am downloading my image and transfering.
func downloadImageToFile(urlString : String, completion: (NSURL?, NSError?) -> Void) {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession.init(configuration: config)
let imageURL = NSURL(string: urlString)
session.downloadTaskWithURL(imageURL!, completionHandler:{(locationURL : NSURL?, response: NSURLResponse?, error: NSError?) in
if (error != nil) {
print("Error: " + (error?.description)!)
completion(nil, error)
}
else {
if let data = NSData(contentsOfURL: locationURL!) {
let documentsDirect = self.documentDirectory()
let saveLocation = documentsDirect.URLByAppendingPathComponent("GCD.png")
let saveWasSuccessfull : Bool = data.writeToURL(saveLocation, atomically: true)
dispatch_async(dispatch_get_main_queue(),{
if (saveWasSuccessfull) {
print("Save Was Successful")
completion(saveLocation, nil)
}
else {
completion(nil, error)
}
})
}
else {
print("Data Download Error")
}
}
}).resume()
}
func documentDirectory() -> NSURL {
let fileManager = NSFileManager.defaultManager()
let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
if let documentDirectory: NSURL = urls.first! as NSURL {
return documentDirectory
}
}
ViewController.swift
let downloader = WebImageDownloader()
downloader.downloadImageToFile(string, completion: { (transferLocation, error) in
if (error != nil) {
}
else {
self.session.transferFile(transferLocation!, metadata: nil)
}
})
func session(session: WCSession, didFinishFileTransfer fileTransfer: WCSessionFileTransfer, error: NSError?) {
if error != nil {
print(error?.description)
}
else{
print("Finished File Transfer Successfully")
}
}
Watch
func session(session: WCSession, didReceiveFile file: WCSessionFile) {
print("File Recieved on Watch")
dispatch_async(dispatch_get_main_queue()) { [weak self] in
if let data = NSData(contentsOfURL: file.fileURL) {
self?.photos.append(data)
self?.updateTable()
}
else {
print(file.fileURL)
}
}
}
Any ideas what is going on here? I have no errors logging to work with anything.
Related
I'm lost with the extension of File in iOS. I can show the files, navigate and show the thumbnails! However, when I click a file it does`t load, only show the text. Here is an image when I click an image:
error click
Here is my code that load the file when has clicked:
override func startProvidingItem(at url: URL, completionHandler: #escaping ((_ error: Error?) -> Void)) {
///TODO CHECK IF EXISTS THE FILE (WITH DATE OR ID)
//guard !fileManager.fileExists(atPath: url.path) else {
// completionHandler(nil)
// return
//}
guard
let identifier = persistentIdentifierForItem(at: url),
let file = FileProviderEnumerator.dictionary[identifier.rawValue]
else {
completionHandler(nil)
return
}
FilesManager.sharedInstance().downloadFile(withIdentifier: file.identifier) { progress in
} withCompletionHandler: { (urlFile, apiError) in
guard let urlFile = urlFile else {
completionHandler(FileProviderError.noContentFromServer)
return
}
do {
let data = try Data(contentsOf: urlFile, options: .alwaysMapped)
let created = self.fileManager.createFile(atPath: urlFile.path, contents:data, attributes:nil)
if(created) {
completionHandler(nil)
} else {
completionHandler(FileProviderError.noContentFromServer)
}
} catch let error{
print(error)
completionHandler(error)
}
/*
do{
let url = urlFile
itemCompletion(data, nil)
} catch let error{
print(error)
itemCompletion(nil, error)
}*/
//
}
}
Is it necessary to do something else? For example the method providePlaceHolder or something like that?
Really thanks in advance an any help with it.
I want to pick video from Images Picker then I want to send video in firebase and retrieve it Please provide code in swift 5, i write code also for sending video on firebase
func downloadImages(folderPath:String,success:#escaping (_ image:UIImage)->(),failure:#escaping (_ error:Error)->()){
// Create a reference with an initial file path and name
let reference = Storage.storage().reference(withPath: "\(folderPath)")
reference.getData(maxSize: (1 * 1024 * 1024 * 1024 * 1024 * 1024)) { (data, error) in
if let _error = error{
print(_error)
failure(_error)
} else {
if let _data = data {
let myImage:UIImage! = UIImage(data: _data)
success(myImage)
}
}
}
}
Upload video On firebase Storage is
func upload(file: URL, completion: #escaping ((_ url : URL?) -> ())) {
let name = "\(Int(Date().timeIntervalSince1970)).mp4"
do {
let data = try Data(contentsOf: file)
let storageRef =
Storage.storage().reference().child("Videos").child(name)
if let uploadData = data as Data? {
let metaData = StorageMetadata()
metaData.contentType = "video/mp4"
storageRef.putData(uploadData, metadata: metaData
, completion: { (metadata, error) in
if let error = error {
completion(nil)
}
else{
storageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
completion(nil)
return
}
completion(downloadURL)
}
print("success")
}
})
}
}catch let error {
print(error.localizedDescription)
}
}
and Get Video From firebase
let reference = Storage.storage().reference().child("Videos").child(folderPath)
reference.getData(maxSize: INT64_MAX) { (data, error) in
if let error = error {
print("Error downloading image data: \(error)")
return
}
reference.getMetadata(completion: { (metadata, metadataErr) in
if let error = metadataErr {
print("Error downloading metadata: \(error)")
return
}
else {
reference.downloadURL { URL, error in
completion(URL)
print(URL)
}
I have implemented the AWSS3 to upload the video to the AWS server and also I want to get the value of task which has been completed using AWSS3TransferUtilityUploadExpression() to show the value on progress bar. But I am not getting the value please see the below code atached.
///1
typealias progressBlock = (_ progress: Double) -> Void //2
typealias completionBlock = (_ response: Any?, _ error: Error?) -> Void //3
//2
// Upload video from local path url
func uploadVideo(videoUrl: URL, progress: progressBlock?, completion: completionBlock?) {
print("video url is \(videoUrl)")
let fileName = self.getUniqueFileName(fileUrl: videoUrl)
print("keyname \(fileName)")
self.uploadfile(fileUrl: videoUrl, fileName: fileName, contenType: "video", progress: progress, completion: completion)
}
//method to upload the video
private func uploadfile(fileUrl: URL,
fileName: String,
contenType: String,
progress: progressBlock?, completion: completionBlock?) {
// Upload progress block
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = {(task, awsProgress) in
guard let uploadProgress = progress else { return }
DispatchQueue.main.async {
debugPrint("completed portion of the task is \(awsProgress.fractionCompleted)")
uploadProgress(awsProgress.fractionCompleted)
//progress!(awsProgress.fractionCompleted)
}
}
// Completion block
var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
completionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
if error == nil {
let url = AWSS3.default().configuration.endpoint.url
let publicURL = url?.appendingPathComponent(self.bucketName).appendingPathComponent(fileName)
if let completionBlock = completion {
completionBlock(publicURL?.absoluteString, nil)
}
} else {
if let completionBlock = completion {
print("error is at completionBlock \(error?.localizedDescription)")
completionBlock(nil, error)
}
}
})
}
// Start uploading using AWSS3TransferUtility
let awsTransferUtility = AWSS3TransferUtility.default()
awsTransferUtility.uploadFile(fileUrl, bucket: bucketName, key: fileName, contentType: contenType, expression: expression, completionHandler: completionHandler).continueWith { (task) -> Any? in
if let error = task.error {
print("error is: \(error.localizedDescription)")
}
if let url = task.result {
// your uploadTask
print("url is \(url)")
}
return nil
}
}
Install cocoapods pod 'AWSS3'.
Here filePath is the path of the file to be uploaded.
func saveModelInAmazonS3() {
let remoteName = fileName + ".mov" //extension of your file name
let S3BucketName = "bucketName"
let uploadRequest = AWSS3TransferManagerUploadRequest()!
uploadRequest.body = filePath!
uploadRequest.key = remoteName
uploadRequest.bucket = S3BucketName
uploadRequest.contentType = "application/zip"
uploadRequest.acl = .publicRead
uploadRequest.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
DispatchQueue.main.async(execute: { // here you can track your progress
let amountUploaded = totalBytesSent
let fileSize = totalBytesExpectedToSend
print("\(amountUploaded)/\(fileSize)")
let progress = (CGFloat(amountUploaded) / CGFloat(fileSize)))
})
}
let transferManager = AWSS3TransferManager.default()
transferManager.upload(uploadRequest).continueWith(block: { (task: AWSTask) -> Any? in
if let error = task.error {
self.delegate.errorInUpload(uploadState: self.uploadState)
print("Upload failed with error: (\(error.localizedDescription))")
}
if task.result != nil {
let url = AWSS3.default().configuration.endpoint.url
print("Uploaded to:\(String(describing: url))")
}
return nil
})
}
I want to download multiple audio files from url and play offline in App . This is what i do in my coding but some time array loop stop downloading . And Also I have one more array to download. and this code is only for download. playing audio is working proper.
override func viewDidLoad() {
super.viewDidLoad()
print("Begin of code")
self.linksToUrls()
self.startDownloadingUrls()
print("End of code")
}
// create a function to start the audio data download
func getAudioDataFromUrl(audioUrl:NSURL, completion: #escaping ((_ data: NSData?) -> Void)) {
URLSession.shared.dataTask(with: audioUrl as URL) { (data, response, error) in
completion(data as NSData?)
print("dfdgfdg",data!)
}.resume()
}
// create another function to save the audio data
func saveAudioData(audio:NSData, destination:NSURL) -> Bool {
if audio.write(to: destination as URL, atomically: true) {
print("The file \"\(destination.lastPathComponent!)\" was successfully saved.")
return true
}
return false
}
// just convert your links to Urls
func linksToUrls(){
print("IntroductoryMusicFile1 = count = ",IntroductoryMusicFile1.count)
audioUrls = NewsAudio1
.map() { NSURL(string: $0) }
.filter() { $0 != nil }
print("introcount",IntroductoryMusicFile1.count)
musicUrls = IntroductoryMusicFile1
.map() { NSURL(string: $0) }
.filter() { $0 != nil }
}
// create a loop to start downloading your urls
func startDownloadingUrls(){
arrayplay.removeAll()
//if (musicUrls = "The URL?"){ }
// let syn = SyncBlock()
for url in 0 ... musicUrls.count-1 {
let aaa = musicUrls[url]
let audioType = audioUrls[url]
print(aaa!)
print("audioType",audioType!)
if aaa == NSURL(string: ""){
arrayplay.append("")
}else{
print("Started downloading \"\(String(describing: aaa?.lastPathComponent!))\".")
let url1 = aaa
let request = URLRequest(url: url1! as URL)
let task = URLSession.shared.dataTask(with: request) {data, response, error in
if let httpResponse = response as? HTTPURLResponse {
print("statusCode: \(httpResponse.statusCode)")
if httpResponse.statusCode == 404{
print("Refresh token...")
// self.audioPlay()
self.arrayplay.append("")
}else{
self.getAudioDataFromUrl(audioUrl: aaa!) { data in
DispatchQueue.main.async() {
print("Finished downloading \"\(String(describing: aaa?.lastPathComponent!))\".")
print("Started saving \"\(String(describing: aaa?.lastPathComponent!))\".")
if self.saveAudioData(audio: data!, destination: self.documentsUrl.appendingPathComponent(aaa!.lastPathComponent!)! as NSURL ) {
// do what ever if writeToURL was successful
// print("",data)
self.arrayplay.append(aaa!.lastPathComponent!)
self.data1 = self.arrayplay as! [String]
print("data1",self.data1)
print("",self.data1.count)
if self.data1.count == self.musicUrls.count {
print("complete")
self.downloadDataAnnotation()
}
//self.synk.complete()
// print("abc")
} else {
// print("The File \"\(url.lastPathComponent!.stringByDeletingPathExtension)\" was not saved.")
}
}
}
}
}
}
task.resume()
}
}
}
Can any one suggest me the better code or any other way to download multiple audio file ...
I've looked many amazon docs but didn't find enough information to upload and download images to S3 using Swift.
How can I do that?
After doing many research I've got this working,
import AWSS3
import AWSCore
Upload:
I assume you have implemented UIImagePickerControllerDelegate already.
Step 1:
Create variable for holding url:
var imageURL = NSURL()
Create upload completion handler obj:
var uploadCompletionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
Step 2: Get Image URL from imagePickerController(_:didFinishPickingMediaWithInfo:):
Set value of imageURL in this delegate method:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
//getting details of image
let uploadFileURL = info[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = uploadFileURL.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String
// getting local path
let localPath = (documentDirectory as NSString).stringByAppendingPathComponent(imageName!)
//getting actual image
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImagePNGRepresentation(image)
data!.writeToFile(localPath, atomically: true)
let imageData = NSData(contentsOfFile: localPath)!
imageURL = NSURL(fileURLWithPath: localPath)
picker.dismissViewControllerAnimated(true, completion: nil)
}
Step 3: Call this uploadImage method after imageURL set to Upload Image to your bucket:
func uploadImage(){
//defining bucket and upload file name
let S3BucketName: String = "bucketName"
let S3UploadKeyName: String = "public/testImage.jpg"
let expression = AWSS3TransferUtilityUploadExpression()
expression.uploadProgress = {(task: AWSS3TransferUtilityTask, bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) in
dispatch_async(dispatch_get_main_queue(), {
let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
print("Progress is: \(progress)")
})
}
self.uploadCompletionHandler = { (task, error) -> Void in
dispatch_async(dispatch_get_main_queue(), {
if ((error) != nil){
print("Failed with error")
print("Error: \(error!)");
}
else{
print("Sucess")
}
})
}
let transferUtility = AWSS3TransferUtility.defaultS3TransferUtility()
transferUtility.uploadFile(imageURL, bucket: S3BucketName, key: S3UploadKeyName, contentType: "image/jpeg", expression: expression, completionHander: uploadCompletionHandler).continueWithBlock { (task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let exception = task.exception {
print("Exception: \(exception.description)")
}
if let _ = task.result {
print("Upload Starting!")
}
return nil;
}
}
Download:
func downloadImage(){
var completionHandler: AWSS3TransferUtilityDownloadCompletionHandlerBlock?
let S3BucketName: String = "bucketName"
let S3DownloadKeyName: String = "public/testImage.jpg"
let expression = AWSS3TransferUtilityDownloadExpression()
expression.downloadProgress = {(task: AWSS3TransferUtilityTask, bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) in
dispatch_async(dispatch_get_main_queue(), {
let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
print("Progress is: \(progress)")
})
}
completionHandler = { (task, location, data, error) -> Void in
dispatch_async(dispatch_get_main_queue(), {
if ((error) != nil){
print("Failed with error")
print("Error: \(error!)")
}
else{
//Set your image
var downloadedImage = UIImage(data: data!)
}
})
}
let transferUtility = AWSS3TransferUtility.defaultS3TransferUtility()
transferUtility.downloadToURL(nil, bucket: S3BucketName, key: S3DownloadKeyName, expression: expression, completionHander: completionHandler).continueWithBlock { (task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let exception = task.exception {
print("Exception: \(exception.description)")
}
if let _ = task.result {
print("Download Starting!")
}
return nil;
}
}
Ref. for upload image
Ref. for download image
Many thanks to jzorz
If all you want is to download the image, this is a much more concise and correct way to do it:
func downloadImage(bucketName: String, fileName: String, completion: (image: UIImage?, error: NSError?) -> Void) {
let transferUtility = AWSS3TransferUtility.defaultS3TransferUtility()
transferUtility.downloadDataFromBucket(bucketName, key: fileName, expression: nil) { (task, url, data, error) in
var resultImage: UIImage?
if let data = data {
resultImage = UIImage(data: data)
}
completion(image: resultImage, error: error)
}
}
func uploadFile(with resource: String, type: String) {
let key = "\(resource).\(type)"
let localImagePath = Bundle.main.path(forResource: resource, ofType: type)
let localImageUrl = URL(fileURLWithPath: localImagePath!)
let transferManager1 = AWSS3TransferUtility.default()
let expression = AWSS3TransferUtilityUploadExpression()
self.uploadCompletionHandler = { (task, error) -> Void in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
if ((error) != nil){
print("Failed with error")
print("Error: \(error!)");
}
else{
print("Sucess")
}
})
}
let transferUtility = AWSS3TransferUtility.default()
transferUtility.uploadFile(localImageUrl, bucket: "", key: key, contentType: "video/mov", expression: expression, completionHandler: uploadCompletionHandler).continueWith { (task) -> AnyObject? in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let _ = task.result {
print("Upload Starting!")
}
return nil;
}
}
#IBAction func uplaodVideo(){
uploadFile(with: "random", type: "mov")
}
The above answers were really helpful to me, but they're quite outdated due to a lot of the nomenclature being changed. So I'm providing an updated version of the answer based on the latest Swift frameworks.
Image Picker Controller:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//getting details of image
let uploadFileURL = info[UIImagePickerController.InfoKey.referenceURL] as! NSURL
let imageName = uploadFileURL.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String
// getting local path
let localPath = (documentDirectory as NSString).appendingPathComponent(imageName!)
//getting actual image
let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
let data = image.pngData()
let imageData = image.pngData()! as NSData
let photoURL = NSURL(fileURLWithPath: localPath)
self.uploadFileURL = photoURL
self.uploadImage(inputData: imageData)
do {
let result = try data?.write(to: photoURL as URL, options: .atomic)
} catch let error {
print(error)
}
picker.dismiss(animated: true, completion: nil)
}
Upload Image:
A quick note on upload image. I hashed my filenames. This is not a necessary step, but I highly recommend to do so in the production stage just to ensure no filenames conflict in your S3 bucket.
func uploadImage(inputData: NSData) {
//defining bucket and upload file name
let S3BucketName: String = "your_bucket_name"
let hashed = SHA256.hash(data: inputData)
let S3UploadKeyName: String = hashed.compactMap { String(format: "%02x", $0) }.joined()
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = {(task: AWSS3TransferUtilityTask, progress: Progress) in
print(progress.fractionCompleted)
}
self.uploadCompletionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
if ((error) != nil){
print("Failed with error")
print("Error: \(error!)")
}
else{
print("Success")
}
})
}
let transferUtility = AWSS3TransferUtility.default()
transferUtility.uploadFile(self.uploadFileURL! as URL, bucket: S3BucketName, key: S3UploadKeyName, contentType: "image/jpeg", expression: expression, completionHandler: uploadCompletionHandler).continueWith { (task) -> AnyObject? in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let _ = task.result {
print("Upload Starting!")
// Do something with uploadTask.
}
return nil
}
}