Hello friend, I want ask something how I can return Conn.xmlParser
because the connectionDidFinishLoading is void and I need this result in order parsing in UITableView how I can use the value of Conn.mlParser?
Please need help.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"DONE. Received Bytes: %d", [Conn.webData length]);
ta=Conn.webData;
if( Conn.xmlParser )
{
[Conn.xmlParser release];
}
Conn.xmlParser = [[NSXMLParser alloc] initWithData: Conn.webData];
[Conn.xmlParser setDelegate: self];
[Conn.xmlParser setShouldResolveExternalEntities: YES];
[Conn.xmlParser parse];
[connection release];
[Conn.webData release];
}
Make sure your delegate also implements the NSXMLParserDelegate protocol. Then you can call didStartElement, didEndElement, didEndDocument, etc.
I usually create an NSArray (or NSMutableArray) that then is populated by objects of the type you are retrieving in the webdata using the NSXMLParser methods mentioned above. Use this array as the datasource in the UITableView's cellForRowAtIndexPath also.
When you reach didEndDocument just call [myUITableView reload] to update the table view. (Unless the tableview and the connection delegate are in two different classes, then you should use KVO to let the tableviewdelegate know the data has been retrieved).
FOLLOW UP:
Rather then just give you are example (of which there are already several on the web), which will just leave you with more questions, I'm going to try to explain what it is that you should understand if you are going to be a successful iOS developer.
And if the steps below seem too daunting for you I suggest you step back and try to tackle the problem slowly one piece at a time. If you still aren't making progress, then go buy a copy of Beginning iPhone 4 Development by Mark, Nutting and LaMarche and then come back to this when you understand the underlying process of Objective-C and iPhone programming better.
To accomplish your goal:
First, you should ask yourself what you are trying to accomplish.
You are getting data from a website (webservice perhaps?) and you want to decode (parse) that information and display it in a tableview. Correct?
So, to solve your problem you have to break apart the question and make sure you understand how to do each part of your task.
Create a seperate Class modeled after the type of data you are going to recieve from your website. If you are getting car objects that specify color, year, model then you should create a Car class with color, year and model properties.
Get Data from a website. You seem to have some idea how to do this since you are already capturing a connection event in the code you showed above. However, do you understand what is happening in ConnectionDidFinishLoading?
Parse the data returned from the website. This requires the use of an XML parser, again you seem to at least know that you need to do something here to parse the data. It also requires a place to store the data that is returned from the website. An array of objects of the type you create in step 1 will be your storage area for the returned and parsed data. Finally, it requires that you understand the specifics of the data that is being passed to you from the website so you understand how to parse the data and store it correctly (and that it really is in XML format, else XMLparsing will not work here).
Display the parsed data in your UITableView. This requires you to understand how to display data in a tableview and how to set the datasource for the tableview.
Second, you should look for sample code you can study that does what you are trying to accomplish and read Apple's documentation to get a firm grip on what has to happen to create your desired result. Look at each part of your task and wherever there is something that is unclear, study that specific issue. How do I use NSXMLParser? How do I display data in a UITableView from an array? etc.
If you don't take the time to really understand how to solve this problem, rather then just copying code, then you will just be back tomorrow with another problem.
Hopefully this will help you solve this problem and help you understand how to solve future problems.
And to get you started, I will give you a link that more or less answers your question.
iPhone Tutorial Creating an RSS feed Reader
Related
I need an answer from a reliable source, about saving NSManagedObjectContexts. Imagine I have a long writing task in in a global queue, I have two contexts as singleton reference (1 of NSMainQueueConcurrency, the other private)...
I have a large task of writing into database and my code look like this:
[privateMOC performBlock^:{
// Here goes a large writing task
................................
// And here goes saving
[privateMOC save:nil];
[mainMOC performBlock^:{
[mainMOC save:nil];
}]
}];
My question is: is it necessary to call save to main context inside a performBlock^ of a privateContext, and another note is that there is no parent-child context structure, but there are two NSPersistentStoreCoordinators.
Thx in advance :)
As usual, it depends what you want and need. :)
In general there's no requirement for one context's save call to be nested in a block passed to another context. You might want to do that in some cases, though. In your sample code, you guarantee that [mainMOC save:nil] won't get called until after [privateMOC save:nil] finishes. Is that important? There's not enough detail in your question to say if it matters in your case, so you'll have to consider that for yourself.
While I'm at it though, you really need to check the results of your save calls. The method returns a boolean to tell you if saving succeeded, and it can return an NSError by reference to tell you why it failed. Your code doesn't check the result and doesn't allow for an NSError-- meaning that if saving ever fails, you've ensured that you won't know that it failed or why. Use the information that the framework is trying to give you.
I have an app that is storing some data using the Cocoa/ObjC initWithCoder / encodeWithCoder style marshaling. Over the life of the app one of the classes that has been removed is an NSDate+Utils category.
The question is - if an NSDate+Utils is serialized to disk, and then deserialized with a later codebase when NSDate+Utils no longer exists; will it come back as an NSDate, or will it crash??
It won't crash. You just need to check whether it's nil. If that' nil, then just skip it, otherwise populate the data to your property. By the way, there is nothing to do with the codebase. It's just whether that local data being stored in the device. Codes are just things that tell device what or how to do stuff.
I wrote a small program to test this. Categories seem to get written as the base class - I assume as long as they don't add fields and/or mess with the withCoder methods.
I have a question regarding the addition of multiple CoreData entries in multiple tables.
I have the following code:
while((item = [enumerator nextObject]))
{
DOCategory *cat;
cat = [[self categoryController] getNewCategory];
[cat setName:[item objectForKey: #"name"]];
[cat setDesc:[item objectForKey: #"description"]];
[cat setLastUpdate:updateTime];
//[[self categoryController] commitChanges];
}
I used to call the commitChanges after each enumeration, and that works, but takes a long time, especially on older devices as the initial load is quite substantial. Therefore I just want to save at the end of the whole operation.
What is the best way to add all those objectors to a NSSet (or NSArray) while preserving the link to the ManagedContext. Normally I would 'copy' them into the set, but that doesn't work here. A simple question, just have a block to seeing the best solution.
(I assume that I don't have to 'commit/save' after every new object I created, so the results are not written to the database yet, but are available for searches as there are different relational objects in the procedure)
Update:
After the suggestion below and more testing, it appears to me that when I haven't saved/committed the context it is not included NSFetchResultController. Is this right and supposed to be the way? Is there a way to do all the operations (including searches to create relations) in 'cache' and then commit once all is done?
Update 2:
In order to get the Managed Object I have a procedure in the Controller-class:
- (DOCategory *) getNewCategory{
return (DOCategory *)[NSEntityDescription insertNewObjectForEntityForName:#"Category" inManagedObjectContext:managedObjectContext];
}
It appears that the code runs fine, including cross references, until I come to adding the final object which uses all the other managed objects. There must be some problem in that code.
Your code is old school Objective-C 1.0 so it would be best to update it. You seldom use enumerators directly like that anymore.
The best way to handle this is to create the new managed objects by inserting them into the context using +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] this both creates the managed object and makes the context aware of it. The context will retain the managed object itself. That's were the "managed" of "managed object" comes from.
The normal practice when making a lot of changes is to change all the objects and then save the context only when you are done making all the changes.
Update:
It appears that the code runs fine,
including cross references, until I
come to adding the final object which
uses all the other managed objects.
There must be some problem in that
code.
That sounds like you might have a problem with the relationship being set properly in the data model itself. I can't say for certain without knowing what your data model looks like.
I discourage the use of cast with insertNewObjectForEntityForName: e.g.
(DOCategory *)[NSEntityDescription insertNewObjectForEntityForName:#"Category" inManagedObjectContext:managedObjectContext];
... because if you have a data model problem, such as not providing the name of the DOCategory class for the DOCatergory entity, the cast will obscure the problem. If there is no class defined the method will return an instance of the generic NSManagedObject class or if you accidentally define the wrong class for the entity e.g. MadeUpClassName instead of DOCategory then the cast will force the runtime to treat the returned object as a DOCategory object. That might work fine until way down in the code.
...it appears to me that when I haven't
saved/committed the context it is not
included NSFetchResultController. Is
this right and supposed to be the way?
Is there a way to do all the
operations (including searches to
create relations) in 'cache' and then
commit once all is done?
Not exactly sure what problem you are seeing. It is best practice to make all changes to all objects and then to save the context instead of saving after every change to any single object. Disk operations are expensive.
If your changes to the context are not reflected in the NSFetchResultsController (FRC) then you most likely did not implement the FRC delegate methods that update the tableview (see FRC docs.) Another possible error is that you've created two context accidentally. If you are using threads, each with a separate context (required practice) then you have to merge the background context with the front context before the changes made in the background are made known to the foreground.
I am attempting to write an app that reads images from the asset library, modifies the image's GPS data and writes it back to the asset library. I store the assets in a mutableArray via the "enumerating assets" methods. Most of the details on how to do the various steps, I got from searching this forum. Thanks!
I have found that when I write the first "asset" via the "writeimagedatatosavedphotosalbum" method, all the elements of the mutableArray associated with the assets' URL became null. Furthermore, I noticed that writing back an image does not replace the original image, but instead creates a second instance of the image.
Just thought I'd pass these results along, in case others had questions. And, of course, I'd be interested in other's comments, observations, etc.
This forum has provided me with great information. Thanks again.
Your ALAsset object is only as good for the amount of time that your ALAssetsLibrary object is around. You either need to do everything you want in the completion block when you get the ALAsset, or store the ALAssetsLibrary in an instance variable so ARC does not deallocate it.
An ALAsset is essentially a Core Data object who can have properties accessed from multiple threads but a NSManagedObject or a subclass of NSManagedObject does not make sense without a parent NSManagedObjectContext much in the same way an ALAsset doesn't make sense without an ALAssetsLibrary.
It is common practice to store the NSManagedObjectContext on the AppDelegate; and while I abstract that functionality into a wrapper/singleton there is a retained reference to the NSManagedObjectContext throughout the app lifecycle. Apply the same logic to the ALAssetsLibrary and everything will works as expected.
In an existing project I have tried to introduce Core Data long after the project was created, so its model is already in place.
I have created the xcdatamodel and added my only class to it.
That class should act as a global storage for objects in my application.
The class properly implement NSManagedObject and I have verified it gets created and saved in context, also retrieved with a fetch result.
The way of saving data in this class is by means of NSMutableArray. But this is just not working. Here's a fragment of this class:
#interface WZMPersistentStore : NSManagedObject<NSCoding> {
NSMutableArray *persistentStorage;
}
#property(nonatomic,retain) NSMutableArray *persistentStorage;
-(void)add:(id)element;
-(void)remove:(id)element;
-(id)objectAtIndex:(NSUInteger)index;
-(NSUInteger)num;
#end
In the implementation I also override the initWithEntity like this:
- (id)initWithEntity:(NSEntityDescription*)entity insertIntoManagedObjectContext:(NSManagedObjectContext*)context {
NSLog(#"init with entity");
[super initWithEntity:entity insertIntoManagedObjectContext:context];
return [self init];
}
The init method only initialize the mutable array, and I can see from the log that it gets properly called by the app delegate when creating entity.
The add method just send message insertObject to persistentStorage.
The questions that come from this:
Am I doing "conceptually" right ? I
mean, is it correct to have instance
variable in managed object and
initialize like I did ?
when ns logging the size of the
persistentStorage I always get 0
even when logging a moment after the
addObject message (edit: that's not
true, I have verified again and I
correctly got 1 added).
The object stored in managed object
class trough persistentStorage are
normal class with attribute. Is
there something I need to do with
them ? I suppose not because I am
not getting any error at runtime.
No, that is not the "right" approach. You can perform initialization of instance variables in awakeFromFetch. Apple guidelines for NSManagedObject subclasses include the following:
You are also discouraged from
overriding
initWithEntity:insertIntoManagedObjectContext:,
dealloc, or finalize. Changing values
in the
initWithEntity:insertIntoManagedObjectContext:
method will not be noticed by the
context and if you are not careful,
those changes may not be saved. Most
initialization customization should be
performed in one of the awake…
methods. If you do override
initWithEntity:insertIntoManagedObjectContext:,
you must make sure you adhere to the
requirements set out in the method
description [...] (NSManagedObject Class Reference)
To really help, I'd need a deeper understanding of what you're trying to accomplish. Regardless, I strongly suggest combing through Apple's Core Data Programming Guide and sample code before proceeding.
I finally manage to solve this issue. Even if I am a newbie in objective-c, I think that introducing core data after the project is done, is not a good idea. Even if many claim it's easy. Unfortunately, all the people saying so, are showing as proof some really simple tutorial of one entity with one string attribute to change.
Instead for my project I ended up writing much code in addition to the existing one, plus some subclassing (NSManagedObject for example) which break the original model. This added code has also to be written carefully. Derived problem can be as simple as an attribute not saved, or dangerous as deleting wrong entities.
Infact, my problem was due to a wrong configuration in decode and encode method in the classes involved in the process of serialization.
For my questions:
-Point one still remain unanswered, because I am not yet confident in objective-c
-Point two, as I said the related object had some problem with encode/code.
-Point three, I was wrong, there's a lot of code to write, depending how complex is the relevant class.