Error on uploading image on aws s3 bucket - file-upload

I get this error on uploading image on aws s3 bucket:
2016-11-12 14:03:43.095 Let's Habit[5144:69128] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSConcreteData initWithBytes:length:copy:deallocator:]: absurd length: 18446744073709551615, maximum size: 9223372036854775808 bytes'
I am using following code for the request:
let fileURL :NSURL = NSURL(string:"\(documentsUrl1)MyappDirectory")!
let filePath = fileURL.path!
let newimg :UIImage = (captureImage?.resizeWithPercentage(0.1))!
let imageData = UIImagePNGRepresentation(newimg)
print(imageData!.length)
imageData!.writeToFile(filePath as String, atomically: true)
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest.body = fileURL
uploadRequest.key = fileName
uploadRequest.bucket = S3BucketName
self.upload(uploadRequest)
func upload(uploadRequest: AWSS3TransferManagerUploadRequest) {
let transferManager = AWSS3TransferManager.defaultS3TransferManager()
transferManager.upload(uploadRequest).continueWithBlock { (task) -> AnyObject! in
print(task)
if let error = task.error {
if error.domain == AWSS3TransferManagerErrorDomain as String {
if let errorCode = AWSS3TransferManagerErrorType(rawValue: error.code) {
switch (errorCode) {
case .Cancelled, .Paused:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
})
break;
default:
print("upload() failed: [\(error)]")
break;
}
} else {
print("upload() failed: [\(error)]")
}
} else {
print("upload() failed: [\(error)]")
}
}
if let exception = task.exception {
print("upload() failed: [\(exception)]")
}
if task.result != nil {
print(task.result)
let url = task.result
print(url)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("https://s3-us-west-2.amazonaws.com/\(uploadRequest.bucket!)/\(uploadRequest.key!)")
})
}
return nil
}
}
How to resolve this error?

I had the same problem. The solution for me was to append the file name to the file URL which was pointing to a directory
uploadRequest.body = fileURL+fileName

Related

Import & Export PDF & Word Doc SwiftUI

I was not able to import or export PDF nor .doc documents to my app. This code below saves selected pdf inside iCloud or phone memory but when I try to view the pdf file it always converts to a document with only text "Hello World".
I guess I need to change allowedContentTypes in .fileImporter and contentType inside .fileExporter but after some research I could not find working example on the web.
#State private var document: MessageDocument = MessageDocument(message: "Hello, World!")
.fileImporter(
isPresented: $isImporting,
allowedContentTypes: [UTType.pdf],
allowsMultipleSelection: false
) { result in
do {
guard let selectedFile: URL = try result.get().first else { return }
//trying to get access to url contents
if (CFURLStartAccessingSecurityScopedResource(selectedFile as CFURL)) {
guard let message = String(data: try Data(contentsOf: selectedFile), encoding: .utf8) else { return }
document.message = message
//done accessing the url
CFURLStopAccessingSecurityScopedResource(selectedFile as CFURL)
}
else {
print("Permission error!")
}
} catch {
// Handle failure.
print(error.localizedDescription)
}
}
.fileExporter(
isPresented: $isExporting,
document: document,
contentType: UTType.data,
defaultFilename: "Message"
) { result in
if case .success = result {
// Handle success.
} else {
// Handle failure.
}
}
}
}
MessageDocument
import SwiftUI
import UniformTypeIdentifiers
struct MessageDocument: FileDocument {
static var readableContentTypes: [UTType] { [.plainText] }
var message: String
init(message: String) {
self.message = message
}
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents,
let string = String(data: data, encoding: .utf8)
else {
throw CocoaError(.fileReadCorruptFile)
}
message = string
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
return FileWrapper(regularFileWithContents: message.data(using: .utf8)!)
}
}

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)

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.

Best practice to safely load image from url

I have the following code snippet to load an image from an url:
let url = NSURL(string: imageUrl)
let data = NSData(contentsOfURL: url!)
let image = UIImage(data: data!)
In case that my variable imageUrl has a valid string value, what is the most secure way to protect this code against possible edge cases?
Following code seems not to be very handy:
if let url = NSURL(string: imageUrl) {
if let data = NSData(contentsOfURL: url) {
if let image = UIImage(data: data) {
// success -> do something with the image...
}
else {
// print error message
}
}
else {
// print error message
}
}
else {
// print error message
}
The best practice is not to use a synchronous method like contentsOfURL to load data from over the network.
The recommended way is NSURLSession which works asynchronously.
This is a simple example with a completion block and an enum with associated types,
it catches all possible errors
enum Result {
case Success(UIImage), Failure(NSString)
}
func loadImage(string : String, completion: (Result) -> ()) {
guard let url = NSURL(string: string) else {
completion(.Failure("Bad URL"))
return
}
NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
if error != nil {
completion(.Failure(error!.localizedDescription))
} else {
guard let image = UIImage(data: data!) else {
completion(.Failure("Could not load image data"))
return
}
completion(.Success(image))
}
}.resume()
}
Call it with:
loadImage("http://myserver.com/path/to/image.png") { result in
switch result {
case .Success(let image) :
// do something with the image
case .Failure(let error) :
print(error)
}
}

How to custom response serialization in Alamofire3

I use Alamofire-beta3, I want to custom response serialization, but I get a error "Cannot call value of non-function type 'NSHTTPURLResponse?' "
https://cloud.githubusercontent.com/assets/7556575/10444657/b0d691fc-719b-11e5-878e-bdd46d03be3b.png
My code is below:
public static func objectSerializer <T: MTLModel> () -> ResponseSerializer <T, MTLError> {
return ResponseSerializer { request, response, data, error in
// Http Error with Http status code
guard error == nil else {
let failureReason = "Network Error"
let error = MTLError.errorWithCode(error!.code, failureReason: failureReason)
return .Failure(error)
}
// data be null
guard let validData = data where validData.length > 0 else {
let failureReason = "JSON could not be serialized. Response data was nil or zero length."
let error = MTLError.errorWithCode(.ResponseDataNull, failureReason: failureReason)
return .Failure(error)
}
do {
let JSON = try NSJSONSerialization.JSONObjectWithData(validData, options: .AllowFragments)
// response data is not a obejct json
guard let json = JSON as? [String : AnyObject] else {
let failureReason = "JSON could not be serialized. Response data is not a obejct JSON"
let error = MTLError.errorWithCode(.JSONSerializeToObjectFailed, failureReason: failureReason)
return .Failure(error)
}
// Http request successful(state 200 OK), but response data not include `Error Section`
guard let errorDict = json["error"] as? [String : AnyObject] else {
let failureReason = "JSON could not be serialized. Http request successful(state 200 OK), but response data not include `Error Section`"
let error = MTLError.errorWithCode(.JSONSerializeErrorSectionFailed, failureReason: failureReason)
return .Failure(error)
}
// mean request failed
if errorDict.count != 0 {
let error: MTLError!
do {
error = try MTLJSONAdapter.modelOfClass(MTLError.self, fromJSONDictionary: errorDict) as! MTLError
} catch _ {
let failureReason = "MTLError object serialize failed"
error = MTLError.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
}
return .Failure(error)
} else {
// mean request successful
let dataDict = json["data"] as? [String : AnyObject]
do {
let object = try MTLJSONAdapter.modelOfClass(T.self, fromJSONDictionary: dataDict) as! T
return .Success(object)
} catch _ {
let failureReason = "\(T.self) object serialize failed"
let error = MTLError.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
return .Failure(error)
}
}
} catch _ {
let failureReason = "Network Error"
let error = MTLError.errorWithCode(error!.code, failureReason: failureReason)
return .Failure(error)
}
}
}
public func responseObject<T: MTLModel> (queue: dispatch_queue_t? = nil, willStart: (() -> Void)? = nil, didStop: (() -> Void)? = nil, completionHandler: Response<T, NSError> -> Void) -> Self
{
willStart?()
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
return response(responseSerializer: Request.objectSerializer(), completionHandler: { (response: Response<T, NSError>) in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
self.printResponse(response)
dispatch_async(queue ?? dispatch_get_main_queue()) {
didStop?()
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
completionHandler(response)
}
})
})
}
I have see https://github.com/Alamofire/Alamofire/issues/817 , but I still don't know how to change my code. Please help me.