Using NSOperationQueue to upload multiple files to server.
//Class B
While uploading multiple files to server at the time move to popviewcontroller (class A). App suddenly crashed.
Is there any way to uploading a files to server without interrupt.
Thanks in Advance
//Class B
-(void)UploadtoS3
{
// Convert file to data from locapathfile here
NSData* imgData = [NSData dataWithContentsOfFile:localFilePath]; //VIDEO FILEPATH OR IMAGEPATH
if(![self upload_NetworkQueue]) // If Queue is not initialized
{
[[self upload_NetworkQueue] cancelAllOperations];
[self setUpload_NetworkQueue:[ASINetworkQueue queue]];
[[self upload_NetworkQueue] setDelegate:self];
[[self upload_NetworkQueue] setRequestDidFailSelector:#selector(upload_RequestFailed:)];
[[self upload_NetworkQueue] setQueueDidFinishSelector:#selector(upload_RequestDone:)];
[[self upload_NetworkQueue] setShowAccurateProgress:YES];
[[self upload_NetworkQueue] setMaxConcurrentOperationCount:1];
}
NSString *s3keyPath = [NSString stringWithFormat:#"/test123/%#",fileName];
NSLog(#"UPLOAD IMAGE S3 FILE NAME ----------- %#",s3keyPath);
request = [ASIS3ObjectRequest PUTRequestForData:imgData withBucket:testBuck key:s3keyPath];
[request setSecretAccessKey:s3SecretKey];
[request setAccessKey:s3AccessKey];
[request setTimeOutSeconds:20];
[request setDelegate:self];
[request setNumberOfTimesToRetryOnTimeout:3];
[request setMimeType:mimeType];
[request setUploadProgressDelegate:self];
[[self upload_NetworkQueue] addOperation:request];
[[self upload_NetworkQueue] go];
}
As the other poster suggested, you should move away from ASI's code. It is no longer supported.
As to your problem, though. My guess is that the code you posted is in a view controller. (Class B in your post) You are setting the view controller as the delegate of your networking class.
Then you are popping from the view controller that initiated the download to another view controller. That causes the view controller that requested the uploads to be deallocated. Thus, when the download queue tries to send a notification to it's delegate, you crash.
In general you should not make a view controller manage application global things like downloads. It would be better to create a singleton class that manages your downloads for you. If you're not familiar with the singleton design pattern then do a google search. There are lots of tutorials online explaining how to set up a singleton in iOS/Objective-C.
On lots of searching about Rabbit MQ I found objective C wrapper for librabbitmq-c whose link is directed to librabbitmq-objc.
For librabbitmq-c link found https://github.com/alanxz/rabbitmq-c.
I tried to integrate both in my application by lots of error are produced like
i) <Cocoa/Cocoa.h> file not found
ii) <amqp.h> file not found
iii)Too few arguements passing to amqp_basic_consume() method in AMQPConsumer.m
iv) Use of undeclared identifier AMQ_PLATFORM in amqp_socket.c file.
v) Use of undeclared identifier AMQP_EXCHANGE_TYPE_DIRECT in AMQPExchange.m
vi) ""---------""----- ""------- AMQP_EXCHANGE_TYPE_FANOUT in ""---""-------
vii)--""-----------""----------- AMQP_EXCHANGE_TYPE_TOPIC in ""----""-------
I also tried latest version of librabbitmq-c from this link https://github.com/alanxz/rabbitmq-c/releases/download/v0.5.2/rabbitmq-c-0.5.2.tar.gz
First and second issue solved by replacing <Cocoa/Cocoa.h> with <Foundation/Foundation.h>
and <amqp.h> with "amqp.h"
But I am not able to solve rest of them
My client library implementation is given below:-
NSString *workQueueName = #"MyQueue";
AMQPExchange *exchange;
AMQPConnection *connection = [[AMQPConnection alloc] init];
[connection connectToHost:#"localhost" onPort:5672];
[connection loginAsUser:#"guest" withPasswort:#"guest" onVHost:#"/"];
AMQPChannel *receiverChannel = [connection openChannel];
AMQPQueue *queue = [[AMQPQueue alloc] initWithName:workQueueName
onChannel:receiverChannel
isPassive:NO
isExclusive:NO
isDurable:NO
getsAutoDeleted:YES];
exchange = [[AMQPExchange alloc] initFanoutExchangeWithName:#"EXCHANGE_NAME" onChannel:receiverChannel isPassive:NO isDurable:NO getsAutoDeleted:NO];
[queue bindToExchange:exchange withKey:workQueueName];
AMQPConsumer *consumer = [[AMQPConsumer alloc] initForQueue:queue onChannel:receiverChannel useAcknowledgements:NO isExclusive:NO receiveLocalMessages:YES];
AMQPConsumerThread *wqThread = [[AMQPConsumerThread alloc] initWithConsumer:consumer];
wqThread.delegate = self;
[wqThread start];
Any help regarding Rabbit MQ will be appreciated, thanks
After long period of time I have solved it.
Please refer this link for library
https://dl.dropboxusercontent.com/u/75870052/AMQPLib.zip
and refer following link for detail...
https://stackoverflow.com/a/26601155/1305001
I am retrieving data via NSURLRequest and it is working perfectly. I have added password protection to that directory now and I am not sure how to configure my code to add in the password for the directory (myStuff)
Can anyone tell me how this is done based on my current code?
Thank you
-(void) retrieve
{
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://XXXXXXX.com/myStuff/test.php"]cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:8.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
receivedData = [[NSMutableData data] retain];
} else {
// Inform the user that the connection failed.
[self showServerAlert];
return;
}
}
//CALL THE OTHER DELEGATE METHODS
The standard URL syntax would be:
http://username:password#XXXXX.com/myStuff/test.php
When doing this though you should not use http. You really want to use https. And don't hardcode the password in your code. A hacker could easily figure it out.
I have been pouring over the internet for days now trying to figure out how to implement this.
I need to request the access token and secret from twitter in order to pass this to a server that will process the users tweets for my application.
I have been following this link https://dev.twitter.com/docs/ios/using-reverse-auth
The problem is step 1. They dont give you an example of step 1.
Here is my code:
NSURL *url = [NSURL URLWithString:TW_OAUTH_URL_REQUEST_TOKEN];
NSDictionary *parameters = #{TW_X_AUTH_MODE_KEY:TW_X_AUTH_MODE_REVERSE_AUTH};
SLRequest *getTwitterAuth = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:parameters];
// Assume that we stored the result of Step 1 into a var 'resultOfStep1'
NSString *S = resultOfStep1;
NSDictionary *step2Params = [[NSMutableDictionary alloc] init];
[step2Params setValue:#"kfLxMJsk7fqIuy8URhleFg" forKey:#"x_reverse_auth_target"];
[step2Params setValue:S forKey:#"x_reverse_auth_parameters"];
NSURL *url2 = [NSURL URLWithString:#"https://api.twitter.com/oauth/access_token"];
SLRequest *stepTwoRequest =
[SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:url2 parameters:step2Params];
// You *MUST* keep the ACAccountStore alive for as long as you need an ACAccount instance
// See WWDC 2011 Session 124 for more info.
self.accountStore = [[ACAccountStore alloc] init];
// We only want to receive Twitter accounts
ACAccountType *twitterType =
[self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Obtain the user's permission to access the store
[self.accountStore requestAccessToAccountsWithType:twitterType
withCompletionHandler:^(BOOL granted, NSError *error) {
if (!granted) {
// handle this scenario gracefully
} else {
// obtain all the local account instances
NSArray *accounts =
[self.accountStore accountsWithAccountType:twitterType];
// for simplicity, we will choose the first account returned - in your app,
// you should ensure that the user chooses the correct Twitter account
// to use with your application. DO NOT FORGET THIS STEP.
[stepTwoRequest setAccount:[accounts objectAtIndex:0]];
// execute the request
[stepTwoRequest performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *responseStr =
[[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding];
// see below for an example response
NSLog(#"The user's info for your server:\n%#", responseStr);
}];
}
}];
I have been trying to figure out how I process the SLRequest in oder to pass it to step 2 from the twitter docs.
I have also used this here: https://github.com/seancook/TWReverseAuthExample
This code is great but very complex. Any help would be greatly appreciated! Thanks!
The reason step one doesn't have any code is that they assume you will do this on your server or before hand or something like that. Basically you need to generate a key that your app will use to convert iOS tokens to normal tokens.
There is a script that will make the request for you here: http://www.ananseproductions.com/twitter-reverse-auth-headaches/ Its written in ruby so you could use something similar if you have a ruby server.
Personally I would have my app request this token from my server, then make the request to twitter, then post the new token back to my server.
Here is a class to help accomplish just this with a single method call that returns a dictionary with the token and token secret.
https://github.com/kbegeman/Twitter-Reverse-Auth
Hope this helps others out!
As of this code https://github.com/seancook/TWReverseAuthExample , it's fairly simple to implement in your own application. I prefer to create reusable classes, so I don't have to implement the same code multiple times. Normally you would create some singleton and work with it on the following tutorial. However the point of this instruction is not to teach you how to create singletons, so for the simplicity sake, we will use AppDelegate.h/m which is easily accessible from all over the application.
All you have to do is the following:
Open yours and Sean Cook's project (the one which URL is above)
Drag and copy Source->Vendor->ABOauthCore group into your project
Select TWAPIManager.h/m, TWSignedRequest.h/m and copy them into your project
Add the below code into your AppDelegate.h file
#property (nonatomic, strong) ACAccountStore* store;
#property (nonatomic, strong) TWAPIManager *apiManager;
#property (nonatomic, strong) NSArray *accounts;
-(void)storeAccountWithAccessToken:(NSString *)token secret:(NSString *)secret;
-(void)performReverseAuth:(id)sender inView:(UIView*)viewToDisplaySheet;
-(void)_refreshTwitterAccounts;
Now paste the following methods into your AppDelegate.m file
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;
-(void)_refreshTwitterAccounts;
-(void)_obtainAccessToAccountsWithBlock:(void (^)(BOOL))block;
-(void)performReverseAuth:(id)sender inView:(UIView*)viewToDisplaySheet;
In some initialization method of your file, or as of this example in: `application: didFinishLaunchingWithOptions' paste the following code:
_store = [[ACAccountStore alloc] init];
_apiManager = [[TWAPIManager alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(_refreshTwitterAccounts) name:ACAccountStoreDidChangeNotification object:nil];
Remember to remove observer using the following code. Paste it in AppDelegate.m:
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Open your app-Info.plist file and add 2 string keys. Take their values from: https://apps.twitter.com/
TWITTER_CONSUMER_KEY
TWITTER_CONSUMER_SECRET
In the View Controller that you want to use to implement twitter features, in the viewDidLoad method, add the following code:
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate _refreshTwitterAccounts];
OK, finally you are ready to start the whole machine. In the View Controller that you want to use to implement twitter features, create UIButton called _reverseAuthBtn and create an IBAction to it. Then in your IBAction paste the following code:
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate performReverseAuth:sender inView:self.view];
Whew, I guess that's it! If I haven't forgotten about anything, you have got Twitter Reverse Oauth implementation, and if you want to use it in multiple view controllers, all you have to do is do steps 1-8, and then paste the code from the steps 9 and 10 into your view controller.
Best regards!
Use this lib, it works perfectly!
https://github.com/nst/STTwitter
Info how to implement: https://github.com/nst/STTwitter#reverse-authentication
:)
In my Main class i am creating an object of my AlbumFetcher class and calling some functions and relasing the object .
AlbumFetcher *_albumFetcher = [[AlbumFetcher alloc] init];
[_albumFetcher getData];
[_albumFetcher release];
When i relaesed the object after calling some functions , ASIHTTP request finish method is not calling and application is crashing . But when i am not releasing the object everything is working perfect . What i have to do
AlbumFetcher *_albumFetcher = [[AlbumFetcher alloc] init];
[_albumFetcher getData];
//[_albumFetcher release]; // now ASIHTTP Request n everything is working fine .....
In AlbumFetcher Class i have this functions ...
-(void)getData{
_fullsizeURL = [NSURL URLWithString:#"http://mysite.com/site/alb_iphone"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:_fullsizeURL];
[request setDelegate:self];
[request setDidFinishSelector:#selector(albumrequestDone:)];
[request setDidFailSelector:#selector(albumrequestFailed:)];
[request startAsynchronous];
}
- (void)albumrequestDone:(ASIHTTPRequest *)request{
// here my code
}
- (void)albumrequestFailed:(ASIHTTPRequest *)request{
// here my code
}
So where i am going wrong and where i have to release the object .
In your case, ASIHTTPRequest works asynchronously, i.e. in another thread. So your request is not done after [_albumFetcher getData] finishes.
Your request is not finished until albumrequestDone:request or albumrequestFailed:request finished. My suggestion is put [self release] at the end of those two functions.