I want to implement a UIAlertView which will show when [[AFHTTPRequestOperationManager manager] GET:] will start doing its job and will disappear automatically when the job is done. One cool extra feature would be if I could display UIProgressView with progress of AFHTTPRequestOperation.
For now I'm checking if a have anything in Core Data and based on that I initialize UIAlertView:
if (![self coreDataHasEntriesForEntityName:#"Group"]) {
downloadingAlert = [[UIAlertView alloc] initWithTitle:#"Pobieranie" message:#"Trwa pobieranie grup" delegate:nil cancelButtonTitle:#"Anuluj" otherButtonTitles:nil, nil];
[self collectData];
} else {
NSError *error;
[[self fetchedResultsController] performFetch:&error];
}
So to prevent from showing this alert when UITableView is already filled with data.
As you can see I'm calling this [self collectData] method which looks like:
-(void)collectData
{
[downloadingAlert show];
[[AFHTTPRequestOperationManager manager] GET:ALL_GROUPS parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSManagedObjectContext *tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
tempContext.parentContext = self.moc;
[tempContext performBlock:^{
// Doing something with responseObject
if (![tempContext save:&error]) {
NSLog(#"Couldn't save: %#", [error localizedDescription]);
}
[self.moc performBlock:^{
NSError *error;
if (![self.moc save:&error]) {
NSLog(#"Couldn't save: %#", [error localizedDescription]);
}
[downloadingAlert dismissWithClickedButtonIndex:0 animated:YES];
[self.writer performBlockAndWait:^{
NSError *error;
if (![self.writer save:&error]) {
NSLog(#"Couldn't save: %#", [error localizedDescription]);
}
}];
}];
}];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Show alert with info about failure
}];
}
As you can see I'm programatically showing this UIAlertView and dismissing it when downloading is completed and UITableView is reloaded. But I have no clue how to add UIProgressView or how to dismiss this UIAlertView without using dismissWithClickedButtonIndex:. Any ideas?
AFNetworking 2.0 HTTP POST Progress
You can receive progress information if you will use the following method
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
fromData:(NSData *)bodyData
progress:(NSProgress * __autoreleasing *)progress
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
of AFHTTPSessionManager class
Related
How to get detail like profile Picture and more Informations while Twitter login in IOS using Fabric .
I write this code --
[[Twitter sharedInstance] logInWithCompletion:^
(TWTRSession *session, NSError *error) {
if (session) {
/* Get user info */
[[[Twitter sharedInstance] APIClient] loadUserWithID:[session userID]
completion:^(TWTRUser *user,
NSError *error)
{
// handle the response or error
if (![error isEqual:nil]) {
NSLog(#"Twitter info -> user = %# ",user);
NSString *urlString = [[NSString alloc]initWithString:user.profileImageLargeURL];
NSURL *url = [[NSURL alloc]initWithString:urlString];
NSData *pullTwitterPP = [[NSData alloc]initWithContentsOfURL:url];
UIImage *profImage = [UIImage imageWithData:pullTwitterPP];
} else {
NSLog(#"Twitter error getting profile : %#", [error localizedDescription]);
}
}];
} else {
NSLog(#"error: %#", [error localizedDescription]);
}
}];
But it show this type of error:
Finally I found the answer my self :
[[Twitter sharedInstance] logInWithCompletion:^
(TWTRSession *session, NSError *error) {
if (session) {
NSLog(#"signed in as %#", [session userName]);
/* Get user info */
NSString *userID = [Twitter sharedInstance].sessionStore.session.userID;
TWTRAPIClient *client = [[TWTRAPIClient alloc] initWithUserID:userID];
[client loadUserWithID:userID completion:^(TWTRUser *user, NSError *error) {
NSLog(#"Profile image url = %#", user.profileImageLargeURL);
}];
} else {
NSLog(#"error: %#", [error localizedDescription]);
}
}];
It gives you url of profile Picture.
Hii i'm trying to get linkedin connection. i have see some same questions but did not find any relevant solution. please help me how can i find connection using latest SDK and which permission i need for connections.
i have used argument as
#define LinkedInApiUrl #"http://api.linkedin.com/v1/people/~/connections:(id,headline,first-name,last-name)"
- (void)requestMeWithToken:(NSString *)accessToken
{
[self.client GET:[NSString stringWithFormat:#"%#?oauth2_access_token=%#&format=json",LinkedInApiUrl,accessToken] parameters:nil success:^(AFHTTPRequestOperation *operation, NSDictionary *result) {
NSLog(#"current user %#", result);
[self linkedinAuthenticationResponse:result error:nil];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failed to fetch current user %#", error);
[self linkedinAuthenticationResponse:nil error:error];
}];
}
- (LIALinkedInHttpClient *)client
{
LIALinkedInApplication *application = [LIALinkedInApplication
applicationWithRedirectURL:[NSString stringWithFormat:#"%#",#"https://www.something.com"]
clientId:LINKEDIN_CLIENT_ID
clientSecret:LINKEDIN_CLIENT_SECRET
state:#"someState"
grantedAccess:#[ LISDK_EMAILADDRESS_PERMISSION, LISDK_BASIC_PROFILE_PERMISSION,LISDK_RW_COMPANY_ADMIN_PERMISSION,LISDK_W_SHARE_PERMISSION ]];
return [LIALinkedInHttpClient clientForApplication:application presentingViewController:self];
}
I am using RestKit and I have following method. I have multiple requests in it and now I am thinking what is best approach (pattern maybe) to do something (for example hide loading alert) after all requests are done. I can set some global boolean values and in every request after it's done change it's own boolean value and check others if are done and then do something. But I am looking for some better solution. Are there some better way?
- (void)loadTypes
{
RKObjectManager *restManager = [RKObjectManager sharedManager];
[restManager getObjectsAtPath:#"remarkGetCategories"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
NSArray* statuses = [mappingResult array];
GetTypesResponse *response = [statuses firstObject];
categoryArray = response.Data;
[_tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
NSLog(#"Hit error: %#", error);
}];
[restManager getObjectsAtPath:#"remarkGetTypes"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
NSArray* statuses = [mappingResult array];
GetTypesResponse *response = [statuses firstObject];
typeArray = response.Data;
[_tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
NSLog(#"Hit error: %#", error);
}];
[restManager getObjectsAtPath:#"remarkGetSubTypes"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
NSArray* statuses = [mappingResult array];
GetTypesResponse *response = [statuses firstObject];
subtypeArray = response.Data;
[_tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
NSLog(#"Hit error: %#", error);
}];
[restManager getObjectsAtPath:#"transactionAccounts"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
NSArray* statuses = [mappingResult array];
GetTypesResponse *response = [statuses firstObject];
NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
for (id object in response.Data) {
BankAccount *bankAccount = [[BankAccount alloc] init];
[bankAccount setValuesForKeysWithDictionary:object];
[mutableArray addObject:bankAccount];
}
accountArray = [NSArray arrayWithArray:mutableArray];
[_tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
NSLog(#"Hit error: %#", error);
}];
}
Edit:
Using ReactiveCocoa (RAC) for first method (remarkGetCategories). This is my helper class for RAC:
#implementation ReactiveCocoaHelper
+ (RACSignal *)signalGetCategories {
return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
RKObjectManager *restManager = [RKObjectManager sharedManager];
[restManager getObjectsAtPath:#"remarkGetCategories"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
[subscriber sendNext:mappingResult];
[subscriber sendCompleted];
}
failure:^(RKObjectRequestOperation *operation, NSError *error)
{
[subscriber sendError:error];
}];
return nil; // `nil` means there's no way to cancel.
}];
}
#end
This is my code for loading data:
RACSignal *signalCategories = [ReactiveCocoaHelper signalGetCategories];
[[RACSignal
merge:#[ signalCategories ]]
subscribeCompleted:^{
NSLog(#"They're both done!");
[_HUD hide:YES];
}];
It's okay and I guess it would be working the way I want when I implement for all methods but for now I am not sure where and how to map result from request to my categoryArray.
Check out ReactiveCocoa, it has an example especially for cases like this, it's the 6th code chunk in the Introduction section. It may seem complicated first, but it worth the effort of taking the time, it can seriously improve productivity, simplicity and stability.
From a RestKit point of view, the restManager has an operationQueue parameter. So, in the success block you can check the operationCount to determine if all of the download and mapping operations are complete.
I need to share the link to Facebook. when user press that link that should take user to another page.
I tried the following code..but it only just share string..it doest not act like hyperlink..
-(void)fbShare
{
[hud show:YES];
NSString *title=[NSString stringWithFormat:#"www.google.com"];
MAAppDelegate *appdelegate = (MAAppDelegate *)[[UIApplication sharedApplication] delegate] ;
if (!appdelegate.session) {
appdelegate.session = [[FBSession alloc]initWithPermissions:[NSArray arrayWithObjects:#"publish_stream",nil]];
}
if (![appdelegate.session isOpen]) {
[appdelegate.session openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error) {
[self Share:title];
}else {
NSLog(#"facebook errror %#",error.description);
[hud hide:YES];
}
}];
} else {
[self Share:title];
}
}
-(void)Share:(NSString *)text
{
MAAppDelegate *appdelegate = (MAAppDelegate *)[[UIApplication sharedApplication] delegate];
UIImage *image = [UIImage imageNamed:#"bath3.png"];
[FBSession setActiveSession:appdelegate.session];
NSData *dataImage=UIImageJPEGRepresentation(image,1.0);
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:text, #"name", dataImage, #"picture", #"image/png", #"content_type", nil];
FBRequest *request=[FBRequest requestWithGraphPath:#"me/photos" parameters:parameters HTTPMethod:#"POST"];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error) {
NSLog(#"Success");
[hud hide:YES];
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Audalize POC" message:#"Shared Successfully" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
} else {
[hud hide:YES];
NSLog(#"failed %#",error.localizedDescription);
}
}];
}
Read this : https://developers.facebook.com/docs/ios/share/
You need to use " link" key for sharing links to facebook.
Ex :
[NSMutableDictionary dictionaryWithObjectsAndKeys:text,#"link", // < ----
dataImage,#"picture",
#"image/png",#"content_type"
,nil];
I have an AFNetworking call that is calling my API and storing the results. I have a similar call that is working just fine this way. However for this one it seems to only be storing the last item.
[client getPath:#"GetItemsByFilter/" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Operation: %#", operation);
NSLog(#"Response: %#", responseObject);
NSArray *customerFieldResults = [responseObject valueForKeyPath:#"details.items"];
NSLog(#"Results: %#", customerFieldResults);
__block NSArray *array;
#try {
[CustomerFields MR_truncateAll];
array = [CustomerFields MR_importFromArray:customerFieldResults];
NSLog(#"done setting array: %#", array);
} #catch (NSException *e) {
NSLog(#"Exception: %#", e);
} #finally {
NSLog(#"tc done");
}
NSLog(#"Array 1: %#", array);
[[NSNotificationCenter defaultCenter] postNotificationName:kCustomerFieldSetComplete object:nil];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Operation: %#", operation);
NSError *jsonError;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[[error localizedRecoverySuggestion] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&jsonError];
NSLog(#"Error: %#", [error localizedRecoverySuggestion]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"Api Error: %#", [dict valueForKey:#"status"]] message:[dict valueForKey:#"statusMessage"] delegate:nil cancelButtonTitle:NSLocalizedString(#"Ok", #"Okay button") otherButtonTitles:nil];
[alert show];
}];
When I do it with a context, it doesn't even save the items. I am sending a notification when the receiving of this information is complete and in that notification I am displaying the results from a [CustomerFields findAll]. Only one item is found with a [CustomerFields findAll].
Array1 shows the complete list of items, but once I get back to the other controller it only returns the very last item that was in the array. Also if I wrap this in a saveWithBlock it will not see any items in the other controller.
Why is it only showing the last record from the import when I do a findAll?
I'm not too familiar with Magical Record, but perhaps you're not saving your core data context?
I assume that the method MR_importFromArray: inserts the records into CoreData?
If that's not the case, you perhaps want to loop through your results and create them one by one?
[client getPath:#"GetItemsByFilter/" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSArray *customerFieldResults = [responseObject valueForKeyPath:#"details.items"];
customerFieldResults = [CustomerFields MR_importFromArray:customerFieldResults];
//loop through array and create records
//save your core data context here
[[NSNotificationCenter defaultCenter] postNotificationName:kCustomerFieldSetComplete object:nil];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error){}];
I figured it out. It turns out the API I was using changed and the field I was using as the relatedByAttribute was coming back blank (a bug) so it was thinking all my records were duplicates and overwriting them.