I am trying to implement a file uploader using NSURLSession.
The file to be uploaded is specified as:
var data: NSData = NSData(contentsOfFile: path)
Suppose, the upload fails for some reason & assuming that I can get an offset to resume upload from.
Is it possible to specify in NSData that we have to start from a given offset (something like do a seek before doing the upload)?
There's a class named NSFileHandle. Personally I never used it but it seems like it does what you need. It has seekToFileOffset method and availableData property so I think you can try it
Related
I'm creating a Commandline tool that will get an input from a user to search for a specific application that supports a certain file extension. For example, if I enter mp4, it will probably show me QuickTime. I'm looking for the specific FileManager manipulation to achieve this in Swift.
I think you are looking for NSWorkspace.urlForApplication(toOpen:). It finds the application that would be opened if you had double clicked on a file, and returns its URL. Since it requires a file to work, you need to first create a temporary empty file somewhere, with the desired extension, then call this method.
let tempFileURL = FileManager.default.temporaryDirectory.appendingPathComponent("foo.mp4")
FileManager.default.createFile(atPath: tempFileURL.path, contents: nil, attributes: nil)
// this gives me the URL for QuickTime Player:
// file:///System/Applications/QuickTime%20Player.app/
let url = NSWorkspace.shared.urlForApplication(toOpen: tempFileURL)
Working on a part of my iOS project that needs to refer to a specific object that the user selects in the main application that is set through a toggle switch that activates the specified object to be used in a Today Extension to record simple objects created by the user in the Today Extension. I am unsure how to go about doing this specifically. I thought about using NSUSerDefaults as the go to method for specifying that object but this is all entirely new to me. Has anyone gone down this path before on here? Does anyone know a way to refer to the specific object you want to store to in the Today Extension?
You can save a reference to a specific managed object by using the objectID property (an instance of NSManagedObjectID), which can be converted to a URI. The URI can then be converted to NSData, which you can save in user defaults.
To save the reference, get the object's ID as a URI:
let objectIDURI = newManagedObject.objectID.URIRepresentation()
Then convert to NSData and save:
let objectIDURIData = NSKeyedArchiver.archivedDataWithRootObject(objectIDURI)
NSUserDefaults.standardUserDefaults().setObject(objectIDURIData, forKey: "savedID")
To get the object back, load the NSData and convert back to an NSURL (the following is simplified, you'll have to handle optionals properly):
let savedObjectIDURIData = NSUserDefaults.standardUserDefaults().objectForKey("savedID") as? NSData
let savedObjectIDURI = NSKeyedUnarchiver.unarchiveObjectWithData(savedObjectIDURIData!) as? NSURL
Then convert the ID back to an NSManagedObjectID and get the managed object:
let savedObjectID = context.persistentStoreCoordinator?.managedObjectIDForURIRepresentation(savedObjectIDURI!)
let savedObject = context.objectWithID(savedObjectID!)
At this point savedObject is the managed object that was saved above.
I'm saving some NSData with writeToFile:atomically: and then want to use that file very shortly afterwards. What is the easiest way to get the NSURL of the file I just saved?
[NSData writeToFile: atomically:] has a path parameter.
Just make the path parameter into a file URL and save that as an instance variable or property and you'll be all set.
Or even better, use [NSData writeToURL: atomically:] (i.e. convert your path into a URL to start with) and save that as a property or instance variable to be used later on.
You can convert a path into a file URL via [[NSURL alloc] initFileURLWithPath:].
And lastly, the real answer to the question you're trying to ask is: no, you can not divine the path or URL from an arbitrary "NSData" object. You'll have to save that information separately or alongside your data in order to keep track of where it came from.
I'm trying to create a way to save the interface of my app in a JSON file. While static elements I can define by their frames and/or center points, the interface does include a single image selected from the photo library. Because some iPhones have 8MP cameras, I can anticipate that some images would be very large.
I would like to be able to save this interface and send it over by email, so another app user can re-open the file and see the same interface with the image included.
Currently I'm using JSONKit to save my data into a JSON object. This means that the email will contain a single JSON file containing both the layout parameters and the image. I've never worked with such large JSON files, so the question is - will having several megs of image data within JSON present parsing issues? Or should I select some other file container that would have : first part JSON file, second part raw image data and then separate that file into a JSON string and a raw data string?
This is what I'm using currently to get a JSON file. After adding NSData to JSON, the convert to json method returns nil
NSString* currentURL = webView.request.mainDocumentURL.absoluteString;
[dictionary setValue:currentURL forKey:#"webViewAddress"];
//this call correctly returns the json string
NSLog(#"%#", [dictionary JSONString]);
NSLog(#"+++++++++++++++++++++++++++++++++++++");
NSData* imageData = UIImagePNGRepresentation(arOverlayView.image);
//after this call, the json returns nil
[dictionary setValue:imageData forKey:kimageData];
NSLog(#"%#", [dictionary JSONString]);
If you are using email as a transport mechanism, your binary data will have to end up as something like Base64 encoded at some point in its life. There is no "raw" format for email, there is only text.
At best you could implement Base85 encoding which is more efficient than Base64
So you are going to have to suck up the large file sizes unless you invent your own transport mechanism - such as a point to point TCP/IP based link.
Obj-C or Monotouch.Net C# answers are fine.
I have a Base64 string that is a PDF document received over a web service. I can get the NSData.
How do I take the NSData and save it as a PDF?
-- I get the NSData this way --
byte[] encodedDataAsBytes = System.Convert.FromBase64String (myBase64String);
string decoded = System.Text.Encoding.Unicode.GetString (encodedDataAsBytes);
NSData data = NSData.FromString (decoded, NSStringEncoding.ASCIIStringEncoding);
The simplest way to save it is probably to use NSData's writeToFile:options:error: method.
I found that using the .NET framework works better than trying to use the iOS framework for this problem. This will take any file and convert it to it's original then save it to the iPhone/iPad device. "path" is just a folder on the dev ice.
using (var f = System.IO.File.Create (path))
{
byte[] encodedDataAsBytes = System.Convert.FromBase64String (Base64PDFString);
f.Write (encodedDataAsBytes, 0, encodedDataAsBytes.Length);
}
I'm working on a project where I recently had to accomplish the same thing you are describing. I get base64 encoded PDF files as strings from a .NET web service which need to be decoded to their original and saved as PDF files in the applications documents directory.
My solution was:
Use ASIHTTPRequest to communicate with the web service.
I then use TBXML to parse incoming xml and get the base64 as an NSString.
To decode the string I use a method from QSUtilities library called decodeBase64WithString.
Finally I save the result with NSData's writeToFile.
I have tested and successfully used this method with PDF files that are up to 25mb. I also had a couple of test runs with a 48mb file but that file made the decodeBase64WithString method take up too much memory and my app crashed. Haven't found a solution to this yet..
If you are working with multiple large files be sure to free up your memory once in a while. I got all my files in one loop in which I had to use my own nsautorelease pool and drain it at the end of the loop to free up any autoreleased objects.