Is there a quick way to POST an NSDictionary to a Python/Django server? - django

I'm looking to send an NSDictionary up to a server running Django, and I would prefer if I had to do little or no work writing an encoder/parser.
Is there an easy way to accomplish this task?

iOS 5 has support for it in the framework. Look at NSJSONSerialization. Here is example code for post. Request object creation has been omitted in the code below.
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSDictionary dictionaryWithObjectsAndKeys:API_KEY, #"apiKey", userName, #"loginUserName", hashPassword, #"hashPassword", nil], #"loginReq", nil];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
NSError *error = nil;
[request setHTTPBody:[NSJSONSerialization dataWithJSONObject:postDict options:0 error:&error]];

iOS doesn't have support to do this as a one-liner, but you could do this:
#interface NSString (URLEncoding)
- (NSString *)urlEncodedUTF8String;
#end
#interface NSURLRequest (DictionaryPost)
+ (NSURLRequest *)postRequestWithURL:(NSURL *)url
parameters:(NSDictionary *)parameters;
#end
#implementation NSString (URLEncoding)
- (NSString *)urlEncodedUTF8String {
return (id)CFURLCreateStringByAddingPercentEscapes(0, (CFStringRef)self, 0,
(CFStringRef)#";/?:#&=$+{}<>,", kCFStringEncodingUTF8);
}
#end
#implementation NSURLRequest (DictionaryPost)
+ (NSURLRequest *)postRequestWithURL:(NSURL *)url
parameters:(NSDictionary *)parameters {
NSMutableString *body = [NSMutableString string];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request addValue:#"application/x-www-form-urlencoded"
forHTTPHeaderField:#"Content-Type"];
for (NSString *key in parameters) {
NSString *val = [parameters objectForKey:key];
if ([body length])
[body appendString:#"&"];
[body appendFormat:#"%#=%#", [[key description] urlEncodedUTF8String],
[[val description] urlEncodedUTF8String]];
}
[request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
return request;
}
#end
Then it's as simple as:
NSURL *url = [NSURL URLWithString:#"http://posttestserver.com/post.php"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:42], #"number",
#"apple", #"brand", nil];
NSURLRequest *request = [NSURLRequest postRequestWithURL:url parameters:params];
[NSURLConnection sendAsynchronousRequest:request queue:nil completionHandler:nil];
Please note that in this example we're not caring about the response. If you care about it, supply a block so you can do something with it.

Related

how to get result from .m function to .mm class Objective-C mixed with Qt

I have Qt application, I'm calling UIImagePickerController to get file path for movie the user selected. So I have static functions in Objective-C which call functions from .m file, when user selects movie I can read selected path in another .m function. Question is, how to get this filePath into some Objective-C class where I can call another Qt classes (like Singleton) and pass this result to proper class ?
Objective-C CL_image_call.mm
#include "cl_image_call.h"
#include "cl_image_func.h"
myCLImageClass* CL_image_obj=NULL;
int CL_ImageCCall::CL_objectiveC_Call() {
//Objective C code calling.....
if( CL_image_obj==NULL ) {
//Allocating the new object for the objective C class we created
CL_image_obj=[[myCLImageClass alloc]init];
}
return 1;
}
void CL_ImageCCall::CL_openMedia() {
[CL_image_obj openMedia];
}
CL_image_call.h
#include <QImage>
#include <QString>
#include <QDebug>
#include <stdio.h>
#include "my_singleton.h"
class CL_ImageCCall
{
public:
static int CL_objectiveC_Call();
static void CL_openMedia();
};
CL_image_func.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#interface myCLImageClass:NSObject
-(void)openMedia;
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
#end
CL_image_func.m
#import "cl_image_func.h"
#interface QIOSViewController : UIViewController
#end
#implementation myCLImageClass
UIImagePickerController *picker=NULL;
UIViewController *viewController=NULL;
NSString *f_path;
-(void)openMedia {
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
viewController = (UIViewController *)([keyWindow rootViewController]);
if (!viewController)
return;
if([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypePhotoLibrary]) {
picker= [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];
[viewController presentViewController:picker animated:YES completion:NULL];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDirPath stringByAppendingPathComponent:#"movie.mov"];
NSLog (#"File Path = %#", filePath);
//filePath is what I need to pass to the rest of my app
[viewController dismissViewControllerAnimated:YES completion:nil];
}
So in CL_image_call.h I have my "my_singleton" where I can reach my whole app, but how to get filePath to this class ?
Best Regards
Marek
Here is the code to export media:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDirPath stringByAppendingPathComponent:#"movie.mov"];
NSLog (#"File Path = %#", filePath);
//filePath is what I need to pass to the rest of my app
NSURL *inputURL = [info objectForKey:UIImagePickerControllerMediaURL];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
// config the session, maybe some option is not what you need, just config by what you need
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
presetName:AVAssetExportPresetMediumQuality];
session.outputURL = [NSURL fileURLWithPath:filePath];
session.outputFileType = AVFileTypeMPEG4;
session.shouldOptimizeForNetworkUse = YES;
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
// do a completion handler
}];
[viewController dismissViewControllerAnimated:YES completion:nil];
}
Then you can visit the output by the filePath, and use when you need.
I have modified code with your suggestion and it does what it should. I'm settings moviePath inside my Qt classes and then I call Objective-C code with this path
NSString *f_path;
//Your objective c code here....
-(void)openMedia:(NSString*)moviePath {
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
f_path=moviePath.copy;
viewController = (UIViewController *)([keyWindow rootViewController]);
if (!viewController)
return;
if([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypePhotoLibrary]) {
picker= [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];
[viewController presentViewController:picker animated:YES completion:NULL];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *inputURL = [info objectForKey:UIImagePickerControllerMediaURL];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
// config the session, maybe some option is not what you need, just config by what you need
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
presetName:AVAssetExportPresetMediumQuality];
session.outputURL = [NSURL fileURLWithPath:f_path];
session.outputFileType = AVFileTypeMPEG4;
session.shouldOptimizeForNetworkUse = YES;
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
// do a completion handler
NSLog (#"export complete = %#", f_path);
}];
[viewController dismissViewControllerAnimated:YES completion:nil];
}
with some trick I can view this movie inside Qt app. One thing that is missing:
I need to know somehow that session has been completed, to refresh file path for MediaPlayer. How can I notify my base class CL_ImageCCall about that. Or actually maybe another Objective-C++ class where I can actually mix Qt and Objective-C ?
Best Regards and thanks for Your help
Marek

Change FBSession with page access token to publish post on fb page as admin

I want to publish a post as admin in a facebook page where the user is admin of the page.
I have the page access token from
[FBRequestConnection startWithGraphPath:#"/me/accounts"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSString *token = [[[result objectForKey:#"data"] objectAtIndex:0] objectForKey:#"access_token"];//accessToken of the page
}];
Now how can i change the FBSession with this token to publish a post on the page as an admin using GraphAPI? FBDocumentation refers to this for openFromAccessTokenData . Please help as i m stuck with this for long time. I m using facebook sdk 3.2. Thanks in advance
NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:token, #"access_token",
titleCell.titleTextView.text,#"message",
[UserDefaultsManager fbPlaceId], #"place",
// fbPhotoId,#"object_attachment",
#"https://www.google.com",#"link",
photoUrl,#"picture",
titleCell.titleTextView.text,#"name",
typeCell.cellTextField.text,#"caption",
descriptionCell.descriptionTextView.text,#"description",
nil];
FBRequest *requestToPost = [[FBRequest alloc] initWithSession:nil
graphPath:#"/me/feed"
parameters:param
HTTPMethod:#"POST"];
FBRequestConnection *requestToPostConnection = [[FBRequestConnection alloc] init];
[requestToPostConnection addRequest:requestToPost completionHandler:^(FBRequestConnection *connection, id result, NSError *error){
if(!error)
{
NSLog(#"facebook result >> %#", result);
NSData *photoData = UIImagePNGRepresentation(promoImage);
NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:token,#"access_token",
photoData,#"source", nil];
FBRequest *requestToPostPhoto = [[FBRequest alloc] initWithSession:nil
graphPath:#"/me/photos"
parameters:param
HTTPMethod:#"POST"];
FBRequestConnection *requestToPostPhotoConnection = [[FBRequestConnection alloc] init];
[requestToPostPhotoConnection addRequest:requestToPostPhoto completionHandler:^(FBRequestConnection *connection, id result, NSError *error){
if(!error)
{
[loadingAlert dismissWithClickedButtonIndex:0 animated:YES];
NSLog(#"facebook result photo>> %#", result);
doneAlert = [[UIAlertView alloc] initWithTitle:#"Success"
message:#""
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
if(self.isUpdatingPromo)
{
doneAlert.message = #"Promo updated successfully";
[doneAlert show];
}
else
{
doneAlert.message = #"Promo created successfully";
[doneAlert show];
}
}
else
{
[loadingAlert dismissWithClickedButtonIndex:0 animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not post photo"
delegate:nil
cancelButtonTitle:#"Dismiss"
otherButtonTitles:nil];
[alert show];
}
}];
[requestToPostPhotoConnection start];
}
else
{
[loadingAlert dismissWithClickedButtonIndex:0 animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not post"
delegate:nil
cancelButtonTitle:#"Dismiss"
otherButtonTitles:nil];
[alert show];
}
}];
[requestToPostConnection start];

Shortening a URL containing & parameters

i have this URL and I am trying to shorten it through bit.ly API. Here is my code
NSString *url = #"http://www.example.com&username=abc&password=123&mode=offline";
NSString *requestStr = [NSString stringWithFormat:#"http://api.bit.ly/v3/shorten?login=%#&apiKey=%#&longUrl=%#&format=txt",login, api_key, url];
requestStr = [requestStr stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestStr]];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *response = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
I am getting a url in response which corresponds to only http://www.example.com
Surprisingly, &username=abc&password=123&mode=offline parts of the url are trimmed.
This happens only when I am doing it through xcode. On the website, it is working properly. PLease help.
NSString *url = #"https://www.googleapis.com/urlshortener/v1/url?key=UR_KEY";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"UR_LONG_URL",#"longUrl", nil];
[request setHTTPBody:[[dict JSONRepresentation] dataUsingEncoding:NSUTF8StringEncoding]];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *response = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

obj-c return block NSString to c++ after request

I'm trying to get this data correctly back to c++, but there are some random crashes. I want to access the data in C++. Sometimes it does, sometime it doesn't. I couldn't find a clear example on how to return this data. Here's my code:
- (NSString*) sendRequestToServer : (CLLocationCoordinate2D) location {
NSLog(#"getting geo from server %# %# ", [NSString stringWithFormat:#"%f", location.latitude],[NSString stringWithFormat:#"%f", location.longitude]);
__block long returnBytesSend = 0;
__block long returnBytesTotal = 0;
__block NSString* tempData = #"" ;
__block BOOL foundNow = false;
self.data = nil;
for (NXOAuth2Account *account in [[NXOAuth2AccountStore sharedStore] accounts]) {
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setObject: [NSString stringWithFormat:#"%f", location.latitude] forKey: #"latitude"];
[params setObject: [NSString stringWithFormat:#"%f", location.longitude] forKey:#"longitude" ];
[params setObject: #"10" forKey: #"radius" ];
[params setObject: #"5" forKey: #"limit"];
NXOAuth2Client *client = [account oauthClient];
NXOAuth2AccessToken *tokenData = [client accessToken];
NSString * clientAccessToken = [tokenData accessToken];
NSString * clientRefreshToken = [tokenData refreshToken];
if (clientAccessToken && clientRefreshToken ){
[NXOAuth2Request performMethod:#"GET"
onResource:[NSURL URLWithString:#"http://www.server.com/list"]
usingParameters: params
withAccount:account
sendProgressHandler:^(unsigned long long bytesSend, unsigned long long bytesTotal) {
returnBytesSend = bytesSend ;
returnBytesTotal = bytesTotal;
}
responseHandler:^(NSURLResponse *response, NSData *responseData2, NSError *error){
NSLog(#"FOUND DATA");
NSRange range = [[[NSString alloc] initWithData:responseData2 encoding:NSUTF8StringEncoding] rangeOfString : #"facebook_id"];
if(range.location != NSNotFound) {
tempData = [[[NSString alloc] initWithData:responseData2 encoding:NSUTF8StringEncoding]retain];
//NSLog(#"%#", tempData);
self.data = [[tempData copy] autorelease];
foundData = true;
}
}];
}
}
return tempData;
}
I was trying to acces the data this way:
#interface oAuthView : UIWebView
#property (nonatomic, strong) __block NSString* data;
#property (nonatomic) __block BOOL foundData;
and in c++ like this:
oAuthView *getWebView;
getWebView =[[oAuthView alloc] initWithFrame:CGRectMake(10,40,300,400)];
if ([getWebView foundData] )
string dataS = string([[artPartView data] UTF8String]));

parse XML to NSArray of NSDictionary - error - why?

I have a problem parsing a XML to NSArray of NSDictionary. I don't know why, but instead of the array gets 2 objects (in this case), it take 2 objects with equal data... Why?
Here's the code:
#interface RLparseXMLToArrayOfDictionarys : NSObject <NSXMLParserDelegate> {
NSMutableArray *arrayWithResult;
NSMutableDictionary *tempDict;
NSMutableString *currentString;
NSString *groupKey;
}
#property (nonatomic, strong) NSString *groupKey;
#property (nonatomic, retain) NSMutableArray *arrayWithResult;
#property (nonatomic, retain) NSMutableDictionary *tempDict;
-(NSArray *)parseXMLWithStringToArray:(NSString *)stringWithXML withGroupKey:(NSString *)groupKeyToIgnore;
#end
#implementation RLparseXMLToArrayOfDictionarys
#synthesize groupKey;
#synthesize arrayWithResult;
#synthesize tempDict;
- (id)init
{
self = [super init];
if (self) {
}
return self;
}
-(NSArray *)parseXMLWithStringToArray:(NSString *)stringWithXML withGroupKey:(NSString *)groupKeyToIgnore{
NSData *currentStringData = [stringWithXML dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:currentStringData];
[parser setDelegate:self];
// Set Parser Options
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
//key to ignore
self.groupKey = groupKeyToIgnore;
if (!arrayWithResult) {
arrayWithResult = [[NSMutableArray alloc] init];
}
if (!tempDict) {
tempDict = [[NSMutableDictionary alloc] init];
}
[parser parse];
NSLog(#"return: %#", arrayWithResult);
return arrayWithResult;
}
#pragma mark -
#pragma mark XML methods
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(!currentString){
currentString = [[NSMutableString alloc] init];
}
[currentString appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSString *currentStringNoWhiteSpace = [currentString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([elementName isEqualToString:groupKey]){
[arrayWithResult addObject:tempDict];
// [tempDict removeObjectsForKeys:[tempDict allKeys]];
}
else if (currentStringNoWhiteSpace != nil)
[tempDict setValue:currentStringNoWhiteSpace forKey:elementName];
currentStringNoWhiteSpace = nil;
currentString = nil;
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
}
#end
Done!
Replace [tempDict removeObjectsForKeys:[tempDict allKeys]];
with tempDict = [[NSMutableDictionary alloc] init];
:)