I need to serialize my NSURL.
object is type of NSManagedObject.
NSURL *objectURIRepresentation = [[object objectID] URIRepresentation];
NSError *error = nil;
NSData *objectIDData = [NSData dataWithContentsOfURL:objectURIRepresentation options:NSDataReadingMapped error:&error];
I get error: (Cocoa error 256.).
Any ideas? Something tells me, using dataWithContentsOfURL: is not good idea.
Update
One more question which is put as a comment mistakenly:
What is the difference between [NSData dataWithContentsOfURL:uri]; and [NSKeyedArchiver archivedDataWithRootObject:uri];?
Thanks.
Firstly, your code does not attempt to serialize a NSURL object, it attempts to create a data object out of the data at the URL returned as the URI of a managed object.
Secondly, that is never going to work.
[NSData dataWithContentsOfURL:] will try to read a file at a particular URL. The URI of a managed object represents an object stored in pieces with many others inside a persistent file like a SQLite database.
The URI only allows a managed object context to identify a particular object in its own store. The URI is gibberish to anything else other than the context.
NSManagedObject does not implement the NSCoder protocol so managed objects cannot be serialized. I'm not sure what you want to do here but you can't do it this way.
As mentioned here Cocoa error 256 core data
error code 256 can occur when an unknown error is occurred in reading the resource or the path has some encoded characters in it.
What it seems to me is you are trying to get the data from NSManagedObject. Hence as #fluchtpunkt suggested you should look for http://cocoawithlove.com/2008/08/safely-fetching-nsmanagedobject-by-uri.html
Now coming to your second question [NSData dataWithContentsOfURL:uri]; returns data for a web url or a local resource in your documents directory. While [NSKeyedArchiver archivedDataWithRootObject:uri]; returns the NSData object containing the encoded form of the object graph whose root object is given.
try to add "Http://" before in the link
Related
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 have a category method that does somethign like this:
#implementation NSData (additions)
- (id)someFunc {
char *buffer = malloc(255);
NSUInteger length = 0;
while (true) {
// . . . fill buffer[length++];
}
realloc(buffer, length);
return [NSData dataWithBytesNoCopy:buffer length:length freeWhenDone:NO];
}
I am then trying to write the returned data (well call this NSData *fileData):
NSError *error;
NSData fileData = [NSData someFunc];
[fileData writeToFile:somePath options:NSDataWritingAtomic error:&error];
I get an error:
Error Domain=NSCocoaErrorDomain
Code=512 "The operation couldn’t be
completed. (Cocoa error 512.)"
UserInfo=0x20deffd0
{NSFilePath=/Users/user/Library/Application
Support/iPhone
Simulator/4.3/Applications/4C315580-153D-4FA7-9474-E17B58832515/Library/Caches/file.pdf,
NSUnderlyingError=0x20de1fe0 "The
operation couldn’t be completed. Bad
address"}
The path exists and is valid. I think the issue is the returned NSData is just a light wrapper around an array allocated with malloc and that writeToFile does not know how to handle this. Does anyone see what I am doing wrong?
When you call realloc you must save the returned pointer, since realloc may allocate a new buffer and copy the content of the old location to that new location. Afterwards the old location is freed and thus invalid. A different malloc call may overwrite that old location.
So you need to do:
buffer = realloc(buffer, length);
That code doesn't make any sense.
show the code that you use to fill the buffer
you have a malloc(), why do you realloc() after the loop? That is a waste of cycles and, if the goal were to expand the buffer if the input data were too long, it won't work as written.
you must check the return value from writeToFile:options:error: to know whether or not there is an error; you cannot check the error directly.
also, don't stick a category like that onto an existing class. In general, it is indicative of an architecture that is fragile and poorly layered. If you do go this route, at least prefix your method with something unique.
It isn't clear why that particular error came up. That path seems a little wonky maybe, how are you generating it?
What I'm trying is this:
1) Create a new manged object
2) Get it's temporary id with [myMO objectID];
3) Convert that ID to an NSURL, so I can save it for future reference:
NSManagedObjectID *moID = [myMO objectID];
NSURL *url = [moID URIRepresentation];
4) Save the managed object context
5) Some time later, fetch that object using the NSURL as ID
NSManagedObjectID *moID = [[context persistentStoreCoordinator] managedObjectIDForURIRepresentation:url];
And guess what: It does not work. I get an empty-stupid object back from
NSManagedObject *myOldMo = [context existingObjectWithID: moID error:&error];
But...as I said...the ID is temporary when creating an managed object. So it does make sense why this doesn't work at all. I must first save the context, and then I get a persistet ID. The real one. Right?
So is that the way to go?
1) Create the managed object
2) Save the context
3) Get the ID as NSURL
4) any time later, for example on your next birthday, access the managed object with the NSURL ;-)
I try to dream of NSManagedObjectID like a DB id which I can write on some yellow postIt sheet and glue on the middle of my monitor, so I refer back to it after lunch. You know... at least like in the old days where we used databases over telnet and executed SQL commands manually to query order information and stuff like that. The ID was the most important and significant thing, all the time.
But Core Data has this somewhat strange NSManagedObjectID thing.
What are your secret strategies? Do you actually recognize many use cases where you would need that NSManagedObjectID? Or is that something I could easily forget with no pain afterwards?
I'm not sure that it's such a big secret. The documentation describes the way to get permanent IDs for managed objects from the NSManagedObjectContext:
- (BOOL)obtainPermanentIDsForObjects:(NSArray *)objects error:(NSError **)error
http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html#//apple_ref/occ/instm/NSManagedObjectContext/obtainPermanentIDsForObjects:error:
My app is accessing data from a remote XML file. I have no issues receiving and parsing the data. However, I'd like to take the most current XML data and store it locally so - in the event that the user's internet service isn't available - the local data from the previous load is used.
Is there a simple way to do this? Or am I going to have to create an algorithm that will create a plist as the xml data is parsed? That seems rather tedious... I was wondering if there was an easier way to save the data as a whole.
Thanks in advance!
I don't know what format your XML data is in as you receive it, but using NSData might be helpful here, because it has very easy-to-use methods for reading/writing data from either a URL or a pathname.
For example:
NSURL *url = [NSURL URLWithString:#"http://www.fubar.com/sample.xml"];
NSData *data = [NSData dataWithContentsOfURL:url]; // Load XML data from web
// construct path within our documents directory
NSString *applicationDocumentsDir =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *storePath = [applicationDocumentsDir stringByAppendingPathComponent:#"sample.xml"];
// write to file atomically (using temp file)
[data writeToFile:storePath atomically:TRUE];
You can also easily convert an NSData object to/from a raw buffer (pointer/length) in memory, so if your data is already downloaded you might do:
NSData *data = [NSData dataWithBytes:ptr length:len]; // Load XML data from memory
// ... continue as above, to write the NSData object to file in Documents dir
I am aware this question has been asked several times, but I was unable to find a definate answer that would best fit my situation.
I want the ability to have the user select an image from the library, and then that image is converted to an NSData type. I then have a requirement to call a .NET C# webservice via a HTTP get so ideally I need the resulting string to be UTF8 encoded.
This is what I have so far:
NSData *dataObj = UIImageJPEGRepresentation(selectedImage, 1.0);
[picker dismissModalViewControllerAnimated:YES];
NSString *content = [[NSString alloc] initWithData:dataObj encoding:NSUTF8StringEncoding];
NSLog(#"%#", content);
The NSLog statement simply produces output as:
2009-11-29 14:13:33.937 TestUpload2[5735:207] (null)
Obviously this isnt what I hoped to achieve, so any help would be great.
Kind Regards
You can't create a UTF-8 encoded string out of just any arbitrary binary data - the data needs to actually be UTF-8 encoded, and the data for your JPEG image obviously is not. Your binary data doesn't represent a string, so you can't directly create a string from it - -[NSString initWithData:encoding:] fails appropriately in your case.
Assuming you're using NSURLConnection (although a similar statement should be true for other methods), you'll construct your NSMutableURLRequest and use -setHTTPBody: which you need to pass an NSData object to. I don't understand why you would be using a GET method here since it sounds like you're going to be uploading this image data to your web service - you should be using POST.