I'm parsing an xml which has data in between the tags like "S |nºconta|".I'm saving this as follows
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
foundText = (NSMutableString *)[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
Where foundText is NSMutableString. But i'm not getting the complete data as "S |nºconta|" instead i'm getting just "nºconta|" where "S |" characters are removed.
Where in xml <Details>S |nºconta|</Details>
At a guess you have illegal characters in the XML - anything outside the regular ASCII range (0-127) should be escaped using a &#xx; or an equivalent named entity.
As far as I can see, it works just fine.
#implementation XMLDELEGATE
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
NSLog(#"didStartElement(%#)",elementName);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"didEndElement(%#)",elementName);
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"foundCharacters(%#)",string);
}
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
static const unsigned char bytes[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Details>S |nºconta|</Details>";
NSXMLParser *p;
NSData *d = [NSData dataWithBytes:bytes length:sizeof(bytes)-1];
p = [[NSXMLParser alloc] initWithData:d];
NSLog(#"data=%#",d);
p.delegate = [XMLDELEGATE new];
[p parse];
}
#end
outputs this:
2014-03-01 15:35:07.272 xmlp2[35923:303] data=<3c3f786d 6c207665 7273696f 6e3d2231 2e302220 656e636f 64696e67 3d225554 462d3822 3f3e3c44 65746169 6c733e53 207c6ec2 ba636f6e 74617c3c 2f446574 61696c73 3e>
2014-03-01 15:35:07.273 xmlp2[35923:303] didStartElement(Details)
2014-03-01 15:35:07.273 xmlp2[35923:303] foundCharacters(S |n)
2014-03-01 15:35:07.273 xmlp2[35923:303] foundCharacters(ºconta|)
2014-03-01 15:35:07.273 xmlp2[35923:303] didEndElement(Details)
As I said in my other answer, you are probably not paying attention to the multiple calls to foundCharacters. It is your responsibility, as delegate, to glue the multiple chunks of string data together in each element (and !CDATA if that happens)
Related
I have a custom class "Bookmark" which contains an NSString. I use a NSMutableArray to store instances of this class thus making a bookmark list which I display in a UITableView with a UITableViewCell prototype.
Would someone please give some advice/example on how to save the instances within the NSMutableArray to a file (and perhaps an example how to load them). I can't get any examples I've searched to work. I've tried converting the array to NSData and using NSKeyedArchiver without success. I've also tried converting to an NSArray but can't get it to work.
Within the custom class I've implemented encodeWithCode and initWithCoder.
I need to save before the app closes and I want to load the list when the app is started.
I'm stuck... :(
EDIT: At the request of Ageektrapped, here are the code snippets:
Inside the implementation of my Bookmark class:
- (void) encodeWithCoder: (NSCoder *) encoder
{
[encoder encodeObject:self.address forKey:#"Address"];
}
- (id) initWithCoder: (NSCoder *) decoder
{
self = [super init];
if (self != nil)
{
self.address = [decoder decodeObjectForKey: #"Address"];
}
return self;
}
In my MasterViewController
self.bookmarks is a NSMutableArray containing bookmark objects. (When the code below is called, there is at least one entry in the bookmarks array.)
NSString *docFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory,NSUserDomainMask,YES) lastObject];
NSString *filename = [docFolder stringByAppendingPathComponent:#"data.plist"];
NSLog(#"File : %#", filename);
NSLog(#"Bookmarks : %d", self.bookmarks.count);
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self.bookmarks ];
if ([data writeToFile: filename atomically: YES])
{
NSLog(#"Successful write");
} else {
NSLog(#"Failed write");
}
I finally figured out what my problem was.
Because I'm debugging on my iPhone device, some folders are not writable. The code I was using was asking for a location in such an area (NSDocumentationDirectory):
After finally finding =>
How can I get a writable path on the iPhone? I understood my problem and got it working.
What I needed to do was replace:
NSString *docFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory,NSUserDomainMask,YES) lastObject];
NSString *filename = [docFolder stringByAppendingPathComponent:#"data.plist"];
with:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES);
NSString *libFolder = [paths objectAtIndex: 0];
NSString *filename = [libFolder stringByAppendingPathComponent: #"data.archive"];
I also changed these lines (to be consistent with the example) from:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self.bookmarks ];
if ([data writeToFile: filename atomically: YES])
{
NSLog(#"Successful write");
} else {
NSLog(#"Failed write");
}
to:
BOOL success = [NSKeyedArchiver archiveRootObject: self.bookmarks toFile: filename];
if (success)
{
NSLog(#"Successful write");
} else {
NSLog(#"Failed write");
}
.
The code to read the file into the NSMutableArray on application startup is:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES);
NSString *libFolder = [paths objectAtIndex: 0];
NSString *filename = [libFolder stringByAppendingPathComponent: #"data.archive"];
self.bookmarks = [NSKeyedUnarchiver unarchiveObjectWithFile: filename];
I need to convert the following to string and display
Overall, the \u2018\u2018typical\u2019\u2019 xyz is broadly expressed
I have tried all sort of uncode conversion
NSData *asciiData = [desc dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *encodedString = [[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding
and:
[NSString stringByReplacingOccurrencesOfString:#"\u2018" withString:#""]
without success.
Kindly suggest me a solution to this.
char cString[] = "\u2018\u2018typical\u2019\u2019";
NSString *string = [NSString stringWithCString:cString encoding:NSUTF8StringEncoding];
NSLog(#"string: %#", string);
NSLog output: string: ‘‘typical’’
or
NSData *data = [NSData dataWithBytes:cString length:strlen(cString)];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"string: %#", string);
NSLog output: string: ‘‘typical’’
I've been struggling with adding assets from the iPhone Photo Library to a AVMutableComposition and then export them. Here is what I got:
Finding the assets: (here I grab the AVURLAsset)
-(void) findAssets {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
[group enumerateAssetsUsingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop){
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
// Do something interesting with the AV asset.
[thumbs addObject:alAsset];
[assets addObject:avAsset];
}else if(alAsset == nil){
[self createScroll];
}
}];
}
failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(#"No groups");
}];
[library release];
}
Here I add a asset to my composition (I use the first object in the array for testing only.
-(void) addToCompositionWithAsset:(AVURLAsset*)_asset{
NSError *editError = nil;
composition = [AVMutableComposition composition];
AVURLAsset* sourceAsset = [assets objectAtIndex:0];
Float64 inSeconds = 1.0;
Float64 outSeconds = 2.0;
// calculate time
CMTime inTime = CMTimeMakeWithSeconds(inSeconds, 600);
CMTime outTime = CMTimeMakeWithSeconds(outSeconds, 600);
CMTime duration = CMTimeSubtract(outTime, inTime);
CMTimeRange editRange = CMTimeRangeMake(inTime, duration);
[composition insertTimeRange:editRange ofAsset:sourceAsset atTime:composition.duration error:&editError];
if (!editError) {
CMTimeGetSeconds (composition.duration);
}
}
And finally I export the comp and here it crashes
-(void)exportComposition {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
NSLog (#"can export: %#", exportSession.supportedFileTypes);
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME];
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputURL = exportURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;//#"com.apple.quicktime-movie";
[exportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog (#"i is in your block, exportin. status is %d",
exportSession.status);
switch (exportSession.status) {
case AVAssetExportSessionStatusFailed:
case AVAssetExportSessionStatusCompleted: {
[self performSelectorOnMainThread:#selector (exportDone:)
withObject:nil
waitUntilDone:NO];
break;
}
};
}];
}
Does anyone have an idea of what it might be? It crashes on
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
And I tried different presets and outputFileTypes.
Thanks
* SOLVED *
I have to answer my own question now when I have solved. It's amazing that I've been struggling with this for a whole day and then I fix it right after posting a question :)
I changed and moved:
composition = [AVMutableComposition
composition];
to:
composition = [[AVMutableComposition
alloc] init];
I think I was too tired when I was working on this yesterday. Thanks guys!
i am working with Mapkit and i am on SDK 4.2, i am having a strange bug here, in fact i have 3 annotation types, "blue.png", red.png,black.png. I am loading these by a flux and depending on the type its will select these annotation types. Everything works fine when the map is loaded i have the the different annotation view, but when i move , zoom in or zoom out the annotation view changes i.e where it was supposed to be blue.png it becomes black.png.
I am actually testing it on device.
Thank you very much :)
Hey veer the problem is that this method is called if the user pans the map to view another location and then comes back to the place where the annotations are plotted.
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id <MKAnnotation>)annotation
I have seen many sample code for map application and this in what most of the people are using.
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if(annotationView)
return annotationView;
else
{
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
pinView.draggable = YES;
pinView.pinColor = MKPinAnnotationColorGreen;
return pinView;
}
return nil;
}
i found the solution - in fact i am using a custom annotation view and having 3 diff types of images :
Soln:
- (AnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
AnnotationView *annotationView = nil;
// determine the type of annotation, and produce the correct type of annotation view for it.
AnnotationDetails* myAnnotation = (AnnotationDetails *)annotation;
if(myAnnotation.annotationType == AnnotationTypeGeo)
{
// annotation for your current position
NSString* identifier = #"geo";
AnnotationView *newAnnotationView = (AnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(nil == newAnnotationView)
{
newAnnotationView = [[[AnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier] autorelease];
}
annotationView = newAnnotationView;
}
else if(myAnnotation.annotationType == AnnotationTypeMyfriends)
{
NSString* identifier = #"friends";
AnnotationView *newAnnotationView = (AnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(nil == newAnnotationView)
{
newAnnotationView = [[[AnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier] autorelease];
}
annotationView = newAnnotationView;
}
}
I am trying to understand how these things work : NSEntityDescription, NSAttributeDescription, attributeType.
I think these few lines of code work, since I get what I expect for the value of X.
Can some one tell me how I should modify the inner part of the loop, that is the line : X++;
in order to get the names and type of the properties in the entity : "myentity" ?
//::::::::::::::::::::::::::: EXPERIMENT
MeDaSyAGAppDelegate *TheAppDelegate=[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *TheContext=[TheAppDelegate managedObjectContext];
NSEntityDescription *TheEntityDesc;
TheEntityDesc=[NSEntityDescription entityForName:#"myentity" inManagedObjectContext:TheContext];
int X=0;
NSDictionary *attribs=[TheEntityDesc attributesByName];
for (NSAttributeDescription *eachA in [attribs allValues]) {
X++;
}
[self showMessageBox:[NSString stringWithFormat:#"X = %d.",X]];
//::::::::::::::::::::::::::: EXPERIMENT
First: Format your code. See below.
Second: try to do this:
NSLog(#"%#",eachA.name);//The name
NSLog(#"%d",[eachA attributeType])//The type, this is an integer
NSLog(#"%#",[eachA attributeValueClassName]);//Class name receiver
See:NSAttributeDescription Class Docs
Formatting: This looks better. (Attributes start with lower cases and use spaces)
//::::::::::::::::::::::::::: EXPERIMENT
MeDaSyAGAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *theContext = [TheAppDelegate managedObjectContext];
NSEntityDescription *theEntityDesc = [NSEntityDescription entityForName:#"myentity" inManagedObjectContext:TheContext];
int X = 0;
NSDictionary *attribs = [theEntityDesc attributesByName];
for (NSAttributeDescription *eachA in [attribs allValues]) {
X++;
}
[self showMessageBox:[NSString stringWithFormat:#"X = %d.", X]];
//::::::::::::::::::::::::::: EXPERIMENT