I am wondering if theres a way to remotely write to a plist file stored on my server. The directory the file is located has write access, but i cannot seem to push the new data. Heres my code:
NSString *accountURL = [NSString stringWithFormat:#"http://www.mywebsite.com//%#.plist",txtUsername.text];
NSURL *url = [NSURL URLWithString:accountURL];
NSMutableDictionary *account = [[NSMutableDictionary alloc] initWithContentsOfURL:url];
[account setObject:#"TEST" forKey:#"LastLogin"];
if ([account writeToURL:url atomically:NO]){
NSLog(#"saved");
}else{
NSLog(#"not saved");
}
The plist file exists because I can read from it with no problem. I just cannot write to the file.
On another note, is this even AppStore-friendly if the accounts will be stored on my server?
You need to parse this web service like this and need to implement the delegate methods of parser.
-(void)startParsingForLoginUser:(NSString*)UserName
{
NSString *urlString = [NSString stringWithFormat:#"http://www.mywebsite.com//%#.plist",UserName]];
NSURL *xmlURL = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:xmlURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0]autorelease];
NSURLResponse *returnedResponse = nil;
NSError *returnedError = nil;
NSData *itemData = [NSURLConnection sendSynchronousRequest:request returningResponse:&returnedResponse error:&returnedError];
xmlParser = [[NSXMLParser alloc] initWithData:itemData];
[xmlParser setDelegate:self];
[xmlParser parse];
}
And then you would be able to write the plist file on server. Moreover, you could also use the method for parsing like POST, PUT and you can also send aSynchronousRequest to the server, that depends upon you.
Read-only is easy. As soon as you get into writing something you get into permissions for: server, application, user.
To solve your problem you need to create a web service that will authenticate the user and application, check permissions and save the file. Typically it would be a server accepting a POST or PUT from your iPhone app (similar to what browsers do for upload)
Related
I wonder how I can check if a file exist on a server or not, without downloading the data first.
I have around 30 different objects and some of them is connected to a movie on a server. At the moment I use NSData to control if the the URL exist, and then shows the movie, or if it doesn't and then alerts the user that there is no video for that object. The code I use for the moment:
NSString *fPath = [[NSString alloc] initWithFormat:#"http://www.myserver/%#", [rows idNr]];
NSURL *videoURL = [NSURL URLWithString:fPath];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
url = [NSURL URLWithString:fPath];
[fPath release];
if (videoData) {
[self performSelectorOnMainThread:#selector(playVideo:) withObject:url waitUntilDone:NO];
} else {
NSLog(#"videodata false");
errorLabel.hidden = NO;
activityView.hidden = YES;
}
"rows idNr" is the name of the object. This method is doing what I want, but the problem is that with NSData it first "downloading" the file, and when the URL is validated as a file, the movie is loading once again in the movieplayer. This means that it takes twice as long to load the file.
Suggestions?
It took me a while to dig out my answer to one of the previous questions on this topic. Quote:
You can use a NSMutableURLRequest to send a HTTP HEAD request
(there’s a method called setHTTPMethod). You’ll get the same
response headers as with GET, but you won’t have to download the whole
resource body. And if you want to get the data synchronously, use the
sendSynchronousRequest… method of NSURLConnection.
This way you’ll know if the file exists and won’t download it all if it does.
Make an URLConnecion object with desired url request and add NSURLConnectionDelegate into .h file like I want to check "yoururl" is exist or not then you need to do is
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString: #"http://www.google.com"]];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
and then you can track http status code in delegate function of NSURLConnectionDelegate
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
int code = [(NSHTTPURLResponse *)response statusCode];
if (code == 404)
{
// website not found
// do your stuff according to your need
}
}
You can also find various status code here.
NSError *err;
if ([videoURL checkResourceIsReachableAndReturnError:&err] == NO)
NSLog(#"wops!");
Here's the code for the accepted answer (for your convenience):
How to make call
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"HEAD"];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
You could do this by checking the size of the file via an FTP server, using the SIZE command. If the file size is zero then the file simply do not exist.
Check here on how to do this.
You could of course also do this by using a NSURLRequest with NSURLConnection, checking for the status to be either 200 (success) or 404 (failed). The 404 status doesn't have to be that the file doesn't exist though, it could also be that the file just couldn't be retrieved.
I have a shopping cart in my app and an underlying data structure that I have serialized into an XML file. Im using the following code to place it on my server. However, nothing happens. Whe I check my server I donot find my file there. So I tried using just a string in place of the file and still the same. Nothing seems to be sent from the app to the server. Im running ths off the simulator.
Im wondering if there is anything wrong with this code.
CartSingleton *Cart = [CartSingleton getSingleton];
id xmlFile = [Cart serializeCart];
//Now send the xml file to the server
NSURL *url = [[NSURL alloc] initWithString:#"http://www.XXXXXXXXX.com/iOS_Files/xmlFile"];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:url];
[req setHTTPMethod:#"POST"];
NSData *paramData = [xmlFile dataUsingEncoding:NSUTF8StringEncoding];
[req setHTTPBody:paramData];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if(theConnection)
{
NSMutableData *data = [[NSMutableData alloc] init];
self.receivedData = data;
[data release];
}
else
{
NSLog(#"Unable to make connection!");
}
I would really appreciate any help.
Thanks
See the class reference, there you can also find the links for the sample applications.
That code
if(theConnection)
{
NSMutableData *data = [[NSMutableData alloc] init];
self.receivedData = data;
[data release];
}
does not start the connection. The receivedData property will have a new NSData object, which is then changed as the response data received.
For the better understanding of the NSUrlConnection usage follow that official guide
What you can do else is to test the server w/o the application using REST Client firefox extension (just send the post request with it and see what happens).
One possible problem with the above code (their may be others also), is that the connection setup will be asynchronous. This is why you had to supply a delegate object above. Therefore, the connection is not actually made until the delegate gets a callback to say it is ready.
Have you implemented any delegate methods?
I am trying to send a query as part a the URL to obtain an XML file, and then trying to parse the XML file using NSXMLParser and initWithContentsOfURL. However the parser is not able to parse the file. I tested the parser with the same file, but this time the file was saved on the server (it was not being generated) and it worked just fine, so I know it is not a problem with the parser.
I have come to think that it does not parse it because I need to load the file before I try to parse it, or give the initWithContentsOfURL time to load the contents. So I tried to put those contents in a NSString and a NSData and using a sleep function as well as using a block but that did not work either.
What would be the best way to go about this problem?
Here is some of the code:
NSString *surl = [NSString stringWithFormat:#"http://lxsrv7.oru.edu/~maria_hernandez/query.xml"];
url = [NSURL URLWithString:surl];
NSString *curl = [[NSString alloc] initWithContentsOfURL:url];
NSLog(#"URL: %#", surl);
NSLog(#"URL Content: %#", curl);
SXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:receivedData];
//Other stuff we have tried:
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:surl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSURLResponse = nil;
NSError = nil;
receivedData = [NSURLConnection sendSynchronousRequest: theRequest returningResponse: &theResponse error: &error];
Let me know if you have more questions or if you wish to see more code.
Thanks!
have you tried setting a delegate for the NSXMLParse that implements the NSXMLParserDelegate which has events for parsing the document
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html
I'm rather new to trying to figure out how JSON and the DropBox API function with the iphone SDK that DB has release for the iPhone. I understand how both technologies work in general and that you have to build a dictionary into a request and get another dictionary back, but I can't find a solid example of how to do anything specifically enough online in Objective C.
I just need one example of how to retrieve for instance the user's profile information by creating a JSON request to fetch info from the drop-box server.
I've been able to log the user in and linking the device using the consumer key and consumer secret but what's next I'm a little at a loss.
MANY thanks for any guidance or examples.
To send your data
Example for POST methods:
url = #"https://api.dropbox.com/<version>/account/"
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:value forKey:#"callback"];
Example for GET methods (URL queries):
NSString *urlString = [[[NSString alloc] initWithString:#"https://api.dropbox.com/<version>/account/info
"] autorelease];
urlString = [urlString stringByAppendingFormat:#"?callback=whatever&status_in_response=something"];
NSURL *url = [[NSURL alloc] initWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDidFinishForThreadID:)];
[request startAsynchronous];
To retrieve JSON values and convert them into Dictionary
SBJsonParser *json = [[SBJsonParser alloc] init];
NSDictionary *dict = (NSDictionary*)[json objectWithString:responseString];
You will need JSON Framework: http://code.google.com/p/json-framework/
And also ASIHTTPRequest: http://allseeing-i.com/ASIHTTPRequest/
Haven't tested it with dropbox, but should be this way.
There are a lot of threads about using UIWebView with caches and/or cookies, but they all seem to relate to remote URLs.
I cannot get cookies to work when "displaying local content" (as the iPhone docs call it).
For example, if I load a plain old HTML file from my bundle resource:
- (void) viewDidLoad {
[super viewDidLoad];
NSString* path = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSURL* url = [NSURL fileURLWithPath:path];
NSData* data = [NSData dataWithContentsOfFile:path];
[web loadData:data MIMEType:#"text/html" textEncodingName:#"us-ascii" baseURL:url];
}
then:
- (void) webViewDidFinishLoad:(UIWebView*)webView {
NSString* result = [web stringByEvaluatingJavaScriptFromString:
#"try{document.cookie='name=value';''+document.cookie;}catch(e){''+e}"];
NSLog(#"Result = '%#'", result);
}
results in:
Result = ''
Setting the URL to be the actual filename rather than the directory prevents getting: Result = 'Error: SECURITY_ERR: DOM Exception 18', but the cookies do not seem to persist.
I have found a satisfactory work-around. By specifying a real URL, such as http://localhost/..., and then intercepting the loading, by subclassing the NSURLCache class, in order to fetch actual local content.
- (NSCachedURLResponse*) cachedResponseForRequest:(NSURLRequest *)request {
NSString* path = [[request URL] path];
NSData* data = [... get content of local file ...];
NSURLResponse *response = [[NSURLResponse alloc]
initWithURL:[request URL]
MIMEType:[self mimeTypeForPath:path]
expectedContentLength:[data length]
textEncodingName:nil];
NSCachedURLResponse* cachedResponse = [[NSCachedURLResponse alloc]
initWithResponse:response
data:data];
[response release];
return [cachedResponse autorelease];
}
Well you could check out NSHTTPCookieStorage class reference. But If you're using the webView for local content, what is the purpose of using cookies? Why not just save that info some other way on your app?
If your aim is to store data in the UIWebView you can also use window.localStorage. It is a hashtable in which you can store max. 5MB of string data.
e.g.
window.localStorage['highscore_level_1']='12000';
alert(window.localStorage['highscore_level_1']);
I've used this succesfully to implement a highscore table in an UIWebView based iPhone App.