Alamofire3 - Alamofire.download : responseArray return response nil - swift

My code ******
let responseDownloaded = Alamofire.download(.GET, url, destination: { (url, response) -> NSURL in
let pathComponent = "recent.json"
let fileManager = NSFileManager.defaultManager()
let directoryURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let fileUrl = directoryURL.URLByAppendingPathComponent(pathComponent)
return fileUrl
})
responseDownloaded.responseArray(keyPath: "aTracks") {[unowned self] (response: Response< [DataMusic], NSError>) in
switch response.result {
case .Success(let music):
// some code
case .Failure(let error):
// some code
}
}
File with json is downloaded to disk, but responseArray give me response nil. What is it wrong ?

Alamofire.download() is not returning any value.
If you need to access a response data:
Alamofire.download(
url,
method: .get,
parameters: parameters,
encoding: JSONEncoding.default,
headers: nil,
to: destination).downloadProgress(closure: { (progress) in
//progress closure
}).response(completionHandler: { (DefaultDownloadResponse) in
//here you able to access the DefaultDownloadResponse
//result closure
})

My solution (with ObjectMapper and SwiftyJSON) :
var fileName: String?
var finalPath: NSURL?
Alamofire.download(.GET, url, destination: { (temporaryURL, response) in
if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
fileName = response.suggestedFilename!
finalPath = directoryURL.URLByAppendingPathComponent(fileName!)
return finalPath!
}
return temporaryURL
})
.response { (request, response, data, error) in
var fileExist: Bool!
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
let filePath = url.URLByAppendingPathComponent("recent.json").path!
let fileManager = NSFileManager.defaultManager()
fileExist = fileManager.fileExistsAtPath(filePath) ? true : false
if fileExist != nil {
let jsonData = JSON(data: NSData(contentsOfURL: NSURL(fileURLWithPath: filePath))!)
if let aTracks = jsonData.dictionary {
if let track = aTracks["aTracks"] {
if let arrTack = Mapper<DataMusic>().mapArray(track.rawString()) {
}
}
}
}
}

Related

How can i find filepath of a file that i downloaded with Alamofire from Firebase Storage

I have some e-pubs on firebase storage.I am downloading specific e-pub with Alamofire downloadURL function but i need e-pubs filePath to open it with FolioReader.
I already tried destinationURL.path but it didn't work with FolioReader
downloadBookRef.downloadURL { (url, error) in
//Done
let destination: DownloadRequest.DownloadFileDestination = {_, _ in
let documentsURL: NSURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
print("documentURL", documentsURL)
let fileURL = documentsURL.appendingPathComponent("kitap\(item).epub")
print("fileURL", fileURL ?? "")
return (fileURL!, [.removePreviousFile, .createIntermediateDirectories])
}
download(url!, to: destination).response { response in
if response.error == nil, let filePath = response.destinationURL?.path {
print("filePath", filePath)
}
}
}

Upload image with some other parameters

I upload image with some other parameters I write this code but can't success in this code I got some error how to resolve this issue
also change parameters type(NSDictionary & String type) and Alamofire update pod.
I face this line Error
multipartFormData.append(value.data(using: String.Encoding.utf8)!,
withName: key)
error is
Value of type 'Any' has no member 'data'
Code is Hear
let parameter : NSDictionary = ["auth_key": UserDefaults.standard.value(forKey: GlobalConstants.kAuthKey)!,
"userid" : UserDefaults.standard.value(forKey: GlobalConstants.kuserId)!,
"eventname" : self.txtEventName.text!,
"eventdescription" : self.textviewDescription.text!,
"event_categories" : self.arrSelectEventID,
"eventshop" : self.selectedOrganizerID,
"eventreef" : self.selectedReefID,
"event_start_date_time" : self.Startdate,
"event_start_time" : self.startTime,
"event_end_date_time" : self.Enddate,
"event_end_time" : self.EnfTime,
"meeting_location" : self.MeetingPoint,
"meeting_location_address" : meetingAddress,
"meeting_location_latitude" : meetinglat,
"meeting_location_longitude" : meetingLong,
"event_ticket_price" : self.txtEventTicketPrice.text! ,
"event_ticket_qty" : self.txtEventTicketQuantity.text!,
"eventvideourl" : self.txtVideoURL.text!,
"recurrence_type" : "none" ,
"end" : self.End,
"end_type" : self.EndType,
"end-count" : self.EndCount,
"create_ticket_on_event" : ""]
let image = self.imgCover.image
let imageData = image?.jpegData(compressionQuality: 1)
Alamofire.upload(multipartFormData: { multipartFormData in
// import image to request
multipartFormData.append(imageData!, withName: "eventimage", fileName: "profile.jpg", mimeType: "image/jpeg")
for (key, value) in parameter {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
}, to: strURL,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
}
upload.responseJSON
{ response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value
{
print("JSON: \(JSON)")
var dic = response.result.value as? [String: Any]
let alert = UIAlertController(title: "Alert", message: dic!["message"] as? String , preferredStyle: .alert)
self.present(alert, animated: true)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
}))
}
}
case .failure(let error):
print(error)
}
})`
I am using this code, Hope so it helps
func jsonCall(withMultipleImagesImage productImages: [UIImage]?, withfieldName strfieldName: String?, classURL urlClass: String?, witCompilation completion: #escaping (_ Dictionary: [AnyHashable: Any]?, _ error: Error?) -> Void) {
self.AddProgressHud()
//NSError *error;
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
// the boundary string : a random string, that will not repeat in post data, to separate post data fields.
let BoundaryConstant = "----------V2ymHFg03ehbqgZCaKO6jy"
// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ
let FileParamConstant = strfieldName
// the server url to which the image (or the media) is uploaded. Use your server url here
let url = URL(string: "\(urlBase)\(urlClass ?? "")")
print("url is \(String(describing: url))")
let request = NSMutableURLRequest()
// if userDefaults.value(forKey: userdefaultAuthHeader) != nil {
// //request.setValue(userDefaults.value(forKey: userdefaultAuthHeader) as? String, forHTTPHeaderField: "Authorization")
// }
request.cachePolicy = .reloadIgnoringLocalCacheData
request.httpShouldHandleCookies = false
request.httpMethod = "POST"
// set Content-Type in HTTP header
let contentType = "multipart/form-data;boundary=\(BoundaryConstant)"
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
// request.setValue(contentType, forHTTPHeaderField: "Content-Type")
// post body
let body = NSMutableData()
var count = 0
for image: UIImage in productImages!{
count += 1
let imageData = UIImage.jpegData(image)
//UIImagePNGRepresentation(image)
if imageData != nil {
if let anEncoding = "--\(BoundaryConstant)\r\n".data(using: .utf8) {
body.append(anEncoding)
}
if let anEncoding = ("Content-Disposition: form-data; name=\"\(String(describing: FileParamConstant!))\"; filename=\"image.png\"\r\n ").data(using: .utf8) {
body.append(anEncoding)
}
if let anEncoding = ("Content-Type: image/png\r\n\r\n").data(using: .utf8) {
body.append(anEncoding)
}
// if let aData = imageData {
// body.append(aData)
// }
if let anEncoding = "\r\n".data(using: .utf8) {
body.append(anEncoding)
}
}
}
if let anEncoding = "--\(BoundaryConstant)--\r\n".data(using: .utf8) {
body.append(anEncoding)
}
// setting the body of the post to the reqeust
request.httpBody = body as Data
// set the content-length
//let postLength = "\(UInt((body as Data).count))"
//request.setValue(postLength, forHTTPHeaderField: "Content-Length")
// set URL
request.url = url!
print("re url \(request.url!)")
var postDataTask: URLSessionDataTask?
postDataTask = session.dataTask(with: request as URLRequest) { data, response, error in
if error == nil {
var dicjson: [AnyHashable: Any]? = nil
DispatchQueue.main.async {
// self.hud.hide(animated: true)
}
print("\(String(data: data!, encoding: .utf8) ?? "")")
if let aData = data {
dicjson = try! JSONSerialization.jsonObject(with: aData, options: []) as? [AnyHashable: Any]
}
completion(dicjson, error)
} else {
print("erro \(String(describing: error?.localizedDescription))")
DispatchQueue.main.async {
// self.hud.hide(animated: true)
}
completion(nil, error)
//GlobalClass.showAlertwithTitle("Server Error", message: error?.description)
}
}
postDataTask?.resume()
}
If you are using alammofire then refer this

Save file to custom folder

In AppDelegate I create hidden folder in .documents if it doesn't exist:
let fileManager = FileManager.default
let path = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let audioKitFilesFolder = path.appendingPathComponent(".AudioKitFilesFolder")
var isDir : ObjCBool = false
if fileManager.fileExists(atPath: audioKitFilesFolder.absoluteString, isDirectory:&isDir) {
if isDir.boolValue {
print("file exists and is a directory")
} else {
print("file exists and is not a directory")
}
} else {
do {
try fileManager.createDirectory(at: audioKitFilesFolder, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Can't Create Folder \(error)")
}
}
In my Networking API I have func that save file from web to .documents. But I need save this file to the my hidden Folder. How I can get path for this folder for my copyItem method?
Newtwork API func:
func downloadFile(id: Int, url: URL, fileName: String) {
var request = URLRequest(url: url)
URLSession.shared.downloadTask(with: url, completionHandler: { location, response, error in
guard let location = location, error == nil else { return }
do {
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent(fileName)
try fileManager.copyItem(at: location, to: fileURL)
try self.router.configureParameters(bodyParameters: ["uuid": UserDefaultsHelper.uuid], urlParameters: nil, request: &request)
} catch {
print(error)
}
}).resume()
URLSession.shared.dataTask(with: request) { data, response, error in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
What happens if you change
do {
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent(fileName)
try fileManager.copyItem(at: location, to: fileURL)
try self.router.configureParameters(bodyParameters: ["uuid": UserDefaultsHelper.uuid], urlParameters: nil, request: &request)
} catch {
to
do {
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let audioKitFilesFolder = documentsURL.appendingPathComponent(".AudioKitFilesFolder")
let fileURL = audioKitFilesFolder.appendingPathComponent(fileName)
try fileManager.copyItem(at: location, to: fileURL)
try self.router.configureParameters(bodyParameters: ["uuid": UserDefaultsHelper.uuid], urlParameters: nil, request: &request)
} catch {
and perhaps remove the . from . AudioKitFilesFolder in all places

How to wait for completion dataTaskWithRequest - Swift?

I try to compare files (tiles) replace the old file on the phone new file from the site, if necessary. But returnPathFile in func pathDir is assigned reference to a file without waiting for the check for and download a new file. How do I get to wait until the completion of testing and loading (if necessary) of the new file?
let urls = { (x: UInt, y: UInt, zoom: UInt) -> NSURL in
let pathtodir = "tiles/\(zoom)/\(x)"
let pathtofile = "\(y).png"
let url = FileManagement.pathDir(pathtodir, file: pathtofile)
return url
}
layerTile = GMSURLTileLayer(URLConstructor: urls)
layerTile.map = self.viewMap!
Method of analyzing whether there is a file in iPhone:
class func pathDir(dir: String, file: String) -> NSURL {
var returnPathFile = NSURL(string: "http://****.***/\(dir)/\(file)")
let url = NSURL(string: "http://*****.***/\(dir)/\(file)")
let pathFile = applicTempDir().stringByAppendingPathComponent("\(dir)/\(file)")
let documentsUrl = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("\(dir)/\(file)")
var attributesToInt: Int!
if filemgr.fileExistsAtPath("\(pathFile)") {
returnPathFile = NSURL(fileURLWithPath: pathFile)
let fileManager = NSFileManager.defaultManager()
do {
let attributes = try fileManager.attributesOfItemAtPath(pathFile)["NSFileCreationDate"] as! NSDate
attributesToInt = Int(attributes.timeIntervalSinceReferenceDate)
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
JsonData.isConnectedToNetwork(url!, dateFileOnTemp: attributesToInt, urlFileOnTemp: documentsUrl, pathFileOnTemp: pathFile, completion:{(path:String, error:NSError!) in
})
if filemgr.fileExistsAtPath("\(pathFile)") {
returnPathFile = NSURL(fileURLWithPath: pathFile)
return returnPathFile!
} else {
return returnPathFile!
}
}
}
Method compere two files:
class func isConnectedToNetwork(url: NSURL, dateFileOnTemp: Int, urlFileOnTemp: NSURL, pathFileOnTemp: String, completion:(path:String, error:NSError!) -> Void) {
var dates: String!
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "HEAD"
let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if (error == nil) {
if let response = response as? NSHTTPURLResponse {
dates = response.allHeaderFields["Last-Modified"] as! String
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'"
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
let dateFileOnSite = dateFormatter.dateFromString(dates)
let dateFileOnSiteInt = Int(dateFileOnSite!.timeIntervalSinceReferenceDate)
if dateFileOnSiteInt > dateFileOnTemp {
FileManagement.reDelFile(pathFileOnTemp)
JsonData.reLoadFileAsync(url, destinationUrl: urlFileOnTemp as NSURL, completion:{(path:String, error:NSError!) in
})
}
}
}
else {
completion(path: urlFileOnTemp.path!, error:error)
}
})
task.resume()
}
Method loads new file:
class func reLoadFileAsync(url: NSURL, destinationUrl: NSURL, completion:(path:String, error:NSError!) -> Void) {
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if (error == nil) {
if let response = response as? NSHTTPURLResponse {
if response.statusCode == 200 {
if data!.writeToURL(destinationUrl, atomically: true) {
completion(path: destinationUrl.path!, error:error)
} else {
let error = NSError(domain:"Error saving file", code:1001, userInfo:nil)
completion(path: destinationUrl.path!, error:error)
}
}
}
}
else {
completion(path: destinationUrl.path!, error:error)
}
})
task.resume()
}
Try to use NSOperationQueue and add your operations accordingly to the queue. This thread might help you NSOperation and NSOperationQueue working thread vs main thread

String(data: data, encoding: NSUTF8StringEncoding) return nil

I am using JSQMessage and pare to send and save video files
if (mediaType == kUTTypeVideo as String) || (mediaType == kUTTypeMovie as String) {
let movieURL = info[UIImagePickerControllerMediaURL] as? NSURL
let videoMediaItem = JSQVideoMediaItem.init(fileURL: movieURL, isReadyToPlay: true)
let message = JSQMessage(senderId: self.senderId, senderDisplayName: senderDisplayName, date: NSDate(), media: videoMediaItem)
self.saveMediaToParse(message, data: NSData(contentsOfURL: movieURL!)!, fileName:"videoFile")
self.messages += [message]
self.publishMessageToChannel(message)
self.finishSendingMessage()
}
func saveMediaToParse(message:JSQMessage, data:NSData, fileName:String) {
let imageFile = PFFile.init(data: data)
let msg = PFObject(className: "test")
msg["senderId"] = message.senderId
msg[fileName] = imageFile
msg["senderDisplayName"] = message.senderDisplayName
msg["user"] = PFUser.currentUser()
msg.saveInBackgroundWithBlock { (success, error) -> Void in
if(error != nil) {
NSLog("error: %#",(error?.localizedDescription)!)
}
}
}
when I am trying to get the video URL from the data as String I get back nil value. What am I doing wrong?
message["videoFile"].getDataInBackgroundWithBlock({ (data, error) -> Void in
if let data = data where error == nil {
**let dataStr = String(data: data, encoding: NSUTF8StringEncoding)**
let movieUrl = NSURL(string: dataStr!)
let videoMediaItem = JSQVideoMediaItem.init(fileURL: movieUrl, isReadyToPlay:true)
jsqMessage = JSQMessage(senderId:message["senderId"] as! String, displayName: message["senderDisplayName"] as! String, media: videoMediaItem)
self.messages.append(jsqMessage)
self.collectionView?.reloadData()
self.scrollToBottomAnimated(true)
}
})
}
self.messages.append(jsqMessage)
Ended up doing
let dataStr = NSTemporaryDirectory() + "temp.mov"
data.writeToFile(dataStr, atomically: true)
let movieUrl = NSURL(fileURLWithPath: dataStr)
Instead of
let dataStr = String(data: data, encoding: NSUTF8StringEncoding)**