When I use XPath I use the following code:
NSArray *version = [doc nodesForXPath:#"/app/version[1]" error:nil];
And if I print the array I get this:
"GDataXMLElement 0x80d5030: {type:1 name:version xml:\"<version>0.6</version>\"}"
But how do I get the "0.6" out of the version? Am I doing this wrong with the array?
EDIT:
I found the solution:
for (GDataXMLElement *version in versions) {
GDataXMLElement *versxml = (GDataXMLElement *) [versions objectAtIndex:0];
NSLog(#"%#", versxml.stringValue);
}
Related
I test to see if a directory is saving and it doesn't seem that it is.
Here is what I have, it's essentially creating a list of which files have been uploaded to Dropbox. DropboxList is declared in the header file and then synchronized.
int i = 0;
DropboxList = [[NSMutableDictionary alloc]init];
do {
[DropboxList setObject:#"NO" forKey:[NSNumber numberWithInt:i]];
i++;
} while (i < sortedFiles.count);
NSLog(#"dropbox list is %#", DropboxList);
NSArray *dropBoxPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dropBoxDocumentsDirectory = [dropBoxPaths objectAtIndex:0];
NSString *dropBoxDataPath = [dropBoxDocumentsDirectory stringByAppendingPathComponent:#"/DropboxUploads"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dropBoxDataPath]) {
[[NSFileManager defaultManager] createDirectoryAtPath:dropBoxDataPath withIntermediateDirectories:NO attributes:nil error:nil];
}
NSString *filePath = [dropBoxDataPath stringByAppendingPathComponent:#"dropboxList.out"];
[DropboxList writeToFile:filePath atomically:YES];
NSMutableDictionary *newDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
NSLog(#"newDictionary list is %#", newDictionary);
Here is my console:
dropbox list is {
0 = NO;
3 = NO;
2 = NO;
1 = NO;
4 = NO;
}
newDictionary list is (null)
I've tried alloc init for the newDictionary before writing and I get the same result. Any ideas?
The problem is with the following line
[DropboxList setObject:#"NO" forKey:[NSNumber numberWithInt:i]];
DropboxList writeToFile only works with the valid property list. For a NSMutableDictionary to be a valid property list object, its keys should be string type instead of NSNumber.
Solution
[DropboxList setObject:#"NO" forKey:[NSString stringWithFormat:#"%d",i]]];
Also, make use of the writeToFile return parameter to validate.
BOOL isWritten = [DropboxList writeToFile:filePath atomically:YES];
if (isWritten)
{
NSMutableDictionary *newDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
NSLog(#"newDictionary list is %#", newDictionary);
{
else
{
NSLog(#"Something went wrong");
}
Okay, so my problem was that I had NSNumbers as the keys, which doesn't work. I made the keys strings, and we're golden.
NSString *xml = #"<?xml version="1.0" encoding="ISO-8859-15"?>
<ServerDateTime DateRequested="" DateSent="20141013_114855">
<DateTime>20141013_114857</DateTime>
</ServerDateTime>";
In above xml, how to find the attribute value of 'DataSent'?
I have tried by following, but i didn't get the value.
CXMLDocument *documentParser = [[CXMLDocument alloc]initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
NSArray *arrayResult = [documentParser nodesForXPath:#"//ServerDateTime" error:nil];
for(CXMLElement *element in arrayResult){
NSString *value = [element name];
if ([value isEqualToString:#"ServerDateTime"]) {
NSString *newLastSyncDate = [[element attributeForName:#"DataSent"] stringValue]; //it gives nil..
}
}
You may want to use XPath-queries to search for elements inside a XML. You have to look up if CXML supports this.
Maybe also take a look at this question.
There someone is searching for a given attribute with an XPath-query.
I'm having an issue properly accessing an NSDictionary built from Flickr data (the flickr.photosets.getPhotos call). Instead of just showing the content of a description tag, it reads the description tag… along with some unnecessary data and quotes.
For example:
NSLog (#"Item description readout: %#", itemDescriptionPre);
yields this response:
Item description readout: {
"_content" = "This is a caption from a photo drawn through Flickr";
}
I've tried to modify the NSString with this
NSString *descripTruncated = [itemDescriptionPre substringFromIndex:17];
But it didn't causes a crash at runtime. It also doesn't address the items at the end of the item. I apologize since NSString modifications seem to be talked about a lot here, but I couldn't find circumstances that mirror mine.
Here is some more context to my code:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Storing incoming data");
NSDictionary *results = [jsonString JSONValue];
NSLog(#"Building NSDictionary.");
NSArray *photos = [[results objectForKey:#"photoset"] objectForKey:#"photo"];
NSLog(#"Building array from dictionary.");
// Loop through each entry in the dictionary...
for (NSDictionary *photo in photos)
{
NSString *title = [photo objectForKey:#"title"];
NSString *description = [photo objectForKey:#"description"];
[photoTitles addObject:title];
[photoDescriptions addObject:description];
}
NSLog(#"Nicer display for results: %# First image title: %# First image description: %#", results, [photoTitles objectAtIndex:0], [photoDescriptions objectAtIndex:0]);
[self updateDisplay];
}
-(void) updateDisplay{
NSString *capTitle = [[photoTitles objectAtIndex:0] uppercaseString];
photoTitleDisplay.text = capTitle;
NSString *itemDescriptionPre = [photoDescriptions objectAtIndex:0];
NSLog (#"Item description readout: %#", itemDescriptionPre);
}
itemDescriptionPre is actually an NSDictionary. This should work:
NSDictionary *itemDescriptionPre = [photoDescriptions objectAtIndex:0];
NSString *itemDescription = [itemDescriptionPre objectForKey:#"_content"];
I'm using MGTwitterEngine. I've found this post where shows a modification to the current version of MGTwitterEngine.
I've applied this modification and when I'm executing the method returns this:
2012-04-10 01:04:17.908 Otsuka On[27519:707] INFO -> retweet response: 07695198-2526-4FF4-BC46-8D39F7719836
But nothing happens in the timeline of the Twitter account.
The method added to TwitterEngine is:
- (NSString *)sendRetweet:(unsigned long)updateID
{
if (updateID == 0){
return nil;
}
NSString *path = [NSString stringWithFormat:#"statuses/retweet/%u.%#", updateID, API_FORMAT];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
[params setObject:[NSString stringWithFormat:#"%u", updateID] forKey:#"id"];
NSString *body = [self _queryStringWithBase:nil parameters:params prefixed:NO];
return [self _sendRequestWithMethod:HTTP_POST_METHOD path:path
queryParameters:params body:body
requestType:MGTwitterUpdateSendRequest
responseType:MGTwitterStatus];
}
Anyone knows what I'm doing wrong?
Thanks.
I use the following method and it works for me:
- (NSString *)sendRetweet:(MGTwitterEngineID)tweetID {
NSString *path = [NSString stringWithFormat:#"statuses/retweet/%llu.%#", tweetID, API_FORMAT];
return [self _sendRequestWithMethod:HTTP_POST_METHOD path:path
queryParameters:nil body:nil
requestType:MGTwitterRetweetSendRequest
responseType:MGTwitterStatus];
}
UPDATE: Yes, try to use this fork: github.com/mattgemmell/MGTwitterEngine
Finally I've solved the problem using NSString parameter as updateID:
- (NSString *)sendRetweet:(NSString *)updateID
{
NSString *path = [NSString stringWithFormat:#"statuses/retweet/%#.%#", updateID, API_FORMAT];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
[params setObject:[NSString stringWithFormat:#"%#", updateID] forKey:#"id"];
NSString *body = [self _queryStringWithBase:nil parameters:params prefixed:NO];
return [self _sendRequestWithMethod:HTTP_POST_METHOD path:path
queryParameters:params body:body
requestType:MGTwitterUpdateSendRequest
responseType:MGTwitterStatus];
}
I created a method to build URLs for me.
- (NSString *)urlFor:(NSString *)path arguments:(NSDictionary *)args
{
NSString *format = #"http://api.example.com/%#?version=2.0.1";
NSMutableString *url = [NSMutableString stringWithFormat:format, path];
if ([args isKindOfClass:[NSDictionary class]]) {
for (NSString *key in args) {
[url appendString:[NSString stringWithFormat:#"&%#=%#", key, [args objectForKey:key]]];
}
}
return url;
}
When I try to build something like below, the URLs aren't encoded, of course.
NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:
#"http://other.com", #"url",
#"ABCDEF", #"apiKey", nil];
NSLog(#"%#", [self urlFor:#"articles" arguments:args]);`
The returned value is http://api.example.com/articles?version=2.0.1&url=http://other.com&apiKey=ABCDEF when it should be http://api.example.com/articles?version=2.0.1&url=http%3A%2F%2Fother.com&apiKey=ABCDEF.
I need to encode both key and value. I searched for something and found CFURLCreateStringByAddingPercentEscapes and stringByAddingPercentEscapesUsingEncoding but none of the tests I made worked.
How can I do it?
IIRC, slashes should be interpreted properly when they're in the query part of a URL. Did you test to see if it still works without encoded slashses? Otherwise, do something like:
if ([args isKindOfClass:[NSDictionary class]]) {
for (NSString *key in [args allKeys]) {
NSString *value = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[args objectForKey:key], NULL, CFSTR("/?&:=#"), kCFStringEncodingUTF8) autorelease];
[url appendString:[NSString stringWithFormat:#"&%#=%#", key, value]];
[value release];
}
}
return url;
Note the value of the 4th argument to CFURLCreateStringByAddingPercentEscapes.
You should consider using Google Toolbox for Mac's GTMNSString+URLArguments; it's designed for exactly this purpose.
I'd recommend our KSFileUtilities set of classes. Your example would then be:
- (NSString *)urlFor:(NSString *)path arguments:(NSDictionary *)args
{
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:args];
[parameters setObject:#"2.0.1" forKey:#"version"];
NSURL *result = [NSURL ks_URLWithScheme:#"http"
host:#"api.example.com"
path:path
queryParameters:parameters;
return [result absoluteString];
}