I'm building an app using the Drupal SDK - everything is great. I have my user log in and successfully upload a photo. However once it's uploaded, I want the image located in the field to display in a UIImageView. I'm using SDImageWeb to get this done, I'm just not sure how to write it? Incoming newb question...
Here is the code that successfully uploads the image to Drupal field called field_profile_photo:
viewcontroller.m
[DIOSFile fileSave:file success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"File uploaded!");
[file setObject:[responseObject objectForKey:#"fid"] forKey:#"fid"];
[file removeObjectForKey:#"file"];
fid = [responseObject objectForKey:#"fid"];
NSLog(#"%#",responseObject);
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject: [NSString stringWithFormat:#"%#", fid] forKey:#"fid"];
NSLog(#"%#", fid);
NSDictionary *fidLangDict = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:dict] forKey:#"und"];
[userData setObject:#"1" forKey:#"uid"];
[userData setObject:fidLangDict forKey:#"field_profile_photo"];
[DIOSUser
userUpdate:userData
success:^(AFHTTPRequestOperation *op, id response) { /* Handle successful operation here */
NSLog(#"User data updated!");
}
failure:^(AFHTTPRequestOperation *op, NSError *err) { /* Handle operation failire here */
NSLog(#"User data failed to update!");
}
];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failed to upload file!");
}];
}
When I refresh this view, I now want the photo uploaded displayed in an imageview. I assume it would look something like this? does anyone know how I can make secondLink the URL generated at field_profile_photo? I hope I'm asking this correctly. Help.
NSString *secondLink = [self.photoData setObject:imageView forKey:#"field_profile_photo"];
[self.imageView sd_setImageWithURL:[NSURL URLWithString:secondLink]];
I have it written like this in my table cell and it works (in another project), however I'm curious as to how I write it when my imageview is just in a view?
NSString *secondLink = [[self.descripData objectAtIndex:indexPath.row] objectForKey:#"field_profile_photo"];
[cell.itemPhoto sd_setImageWithURL:[NSURL URLWithString:secondLink]];
Related
I am using AFNetworking and download image if it is new image.
After I read though stackoverflow, currently, I am doing like this.
If the image is not modified, there will be cache in http header and I use that fact to check whether image is modified or not.
It is working well for most iOS. But, on iPhone 6s iOS 9.2.1, it always assume as new image.
How shall I detect whether image in server is modified already by using AFNetworking or may be NSUrlConnection?
- (void)downloadSplashScreenFromURL:(NSString *)urlStr
{
BOOL __block responseFromCache = YES; // yes by default
void (^requestSuccessBlock)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) {
// response was returned from the server, not from cache
NSString *assestName = [urlStr lastPathComponent];
////WRITE TO FILEPATH
NSString *filePath = [splashDirectory() stringByAppendingString:
[NSString stringWithFormat:#"/%#", assestName]];
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
DLog(#"Splash : Splash image is empty");
NSData *pngData = UIImagePNGRepresentation(responseObject);
[pngData writeToFile:filePath atomically:YES];
return ;
}
if (responseFromCache) {
// response was returned from cache
DLog(#"SPLASH - RESPONSE FROM CACHE: %#", responseObject);
}
else {
DLog(#"SPLASH - NEW IMAGES FROM SERVER \n Response: %#", responseObject);
NSData *pngData = UIImagePNGRepresentation(responseObject);
[pngData writeToFile:filePath atomically:YES];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:USERDEFAULTS_SPLASH_SCREEN];
[[SplashHelper sharedInstance] showSplash:YES inWindow:[AppDelegate instance].window andSuccessBlock:^{
[[AppDelegate instance] startRunning];
}];
}
};
void (^requestFailureBlock)(AFHTTPRequestOperation *operation, NSError *error) = ^(AFHTTPRequestOperation *operation, NSError *error) {
NSInteger statusCode = operation.response.statusCode;
DLog(#"SPLASH - status code: %lu \nERROR: %#", (long)statusCode, [error localizedDescription]);
DLog(#"SPLASH - ERROR: %#", error);
};
DLog(#"Splash : CALL SPLASH SCREEN HELPER");
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *operation = [manager GET:urlStr
parameters:nil
success:requestSuccessBlock
failure:requestFailureBlock];
[manager.requestSerializer setTimeoutInterval:3.0f];
operation.responseSerializer = [AFImageResponseSerializer serializer];
[operation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
// this will be called whenever server returns status code 200, not 304
responseFromCache = NO;
DLog(#"Splash : cachedResponse = %#", cachedResponse);
return cachedResponse;
}];
}
I'm using #import "UIImageView+AFNetworking.h" category in my app to load an image from my server to app. Its working great, whenever an an update made for images on server, it'll generate new URLs, thus when I request with new URLs, AFNetworking will not find a cached image and will load new images from server.
And you should also check this, How do I get cached image stored by AFNetworking's UIImageView category? - there comes requirement when you needs to look after for an image inside your app's cache area.
i need fetch data from server in background mode ios. but when i run app in background, didReceiveData method never called. in foreground it work fine.
when app run in background then app request data from applicationDidEnterBackground method. i cannot why didReceiveData method not call.
please help me!
i use this way may help you..
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setObject:string forKey:#"data"];
[dic setObject:ADDD_DATA_UPGRADE forKey:#"cn"];
[dic setObject:#"true" forKey:#"mode"];
[self login:dic];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
});
});
}
-(void)login:(NSDictionary*)dic
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:UPDATION_ON_SERVER_TIME];
SAAPIClient *manager = [SAAPIClient sharedClient];
[[manager responseSerializer] setAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
[manager postPath:#"" parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject)
{
if([[responseObject objectForKey:#"status"] boolValue])
{
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
[self parseResponseFromJson:responseObject];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:UPDATION_ON_SERVER_TIME];
NSLog(#"Success: %# ***** %#", operation.responseString, error);
}];
first I'd like to say that the issue I am having is in regards to how my own code is set, not IOS or AFNetworking.
I am going to show 1 example where a view is not refreshing immediately even though the updated JSON response object from the server is being recieved.
There are 2 views being used in the first view the button below takes the user to a second view where he can upload an image that will then be displayed in the first view.
- (IBAction)editImage:(id)sender {
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
TDUserProfileViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"TDUserProfileImageEditViewController"];
[self.navigationController pushViewController:vc animated:YES];
}
Below is the code that uploads the new data to the server and then gets new data regarding the images's address on the server.
- (IBAction)dataSubmitToServer{
// NSLog(#"photo: %#", self.photoData);
NSString * userID = [[NSUserDefaults standardUserDefaults] objectForKey:USERID];
//make the call to the web API
NSString* command = #"setProfilePhoto";
self.params =[NSMutableDictionary dictionaryWithObjectsAndKeys:command, #"command", userID, #"userid", nil];
//////////////////
NSLog(#"%#", self.params);
self.photoName = #"newname.png";
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:BaseURLString parameters:self.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:UIImageJPEGRepresentation(self.userPhoto.image, 1)
name:#"image"
fileName:self.photoName
mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
[TDPublicFunctions showDefaultAlert:#"Error" body:[error description]];
}];
[self getNewProfileData];
[[NSUserDefaults standardUserDefaults] synchronize];
}
-(void)getNewProfileData{
/*start getting new data for profile pic and status message*/
NSString* command = #"displayProfileData";
NSString * userID = [[NSUserDefaults standardUserDefaults] objectForKey:USERID];
NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:command, #"command", userID,#"userid", nil];
NSLog( #"%#", params);
[SVProgressHUD showWithStatus:#"Loading..." maskType:SVProgressHUDMaskTypeBlack];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:BaseURLString parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
[SVProgressHUD dismiss];
if([responseObject objectForKey:#"error"])
{
[[[UIAlertView alloc] initWithTitle:#"Data Retrieval Error" message:[responseObject description] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil] show];
}
else
{
NSString * profilePhoto = [[[responseObject objectForKey:#"result"] objectAtIndex:0] objectForKey:#"profile_picture"];
NSString * status = [[[responseObject objectForKey:#"result"] objectAtIndex:0] objectForKey:#"status"];
NSString * statusMsg = [[[responseObject objectForKey:#"result"] objectAtIndex:0] objectForKey:#"status_message"];
if(profilePhoto && ![profilePhoto isKindOfClass:[NSNull class]])
[[NSUserDefaults standardUserDefaults] setObject:profilePhoto forKey:PROFILE_PHOTO];
if(status && ![status isKindOfClass:[NSNull class]])
[[NSUserDefaults standardUserDefaults] setObject:status forKey:STATUS];
if(statusMsg && ![statusMsg isKindOfClass:[NSNull class]])
[[NSUserDefaults standardUserDefaults] setObject:statusMsg forKey:STATUS_MESSAGE];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
//end of getting data for status message and profile pic
}
Now once this above process is over the HUD is supposed to stop and when the back button on the view is hit there should be a newly uploaded image in the first view. The code below is the last of many things that I have tried in order to get the view with the image to refresh:
-(void) viewWillAppear:(BOOL)animated
{
NSString * profPic = [[NSUserDefaults standardUserDefaults] objectForKey:PROFILE_PHOTO];
NSLog(#"profilepic: %#", profPic);
// NSString* status = [[NSUserDefaults standardUserDefaults] objectForKey:STATUS];
NSString * statusMsg = [[NSUserDefaults standardUserDefaults] objectForKey:STATUS_MESSAGE];
if(profPic)
[photo loadIconForProduct:profPic];
if(statusMsg)
statusMsgView.text = statusMsg;
//self.view=nil;
//[self viewDidLoad];
[self getFriendsList];
[photo setNeedsDisplay];
[self.view setNeedsDisplay];
}
After an image is uploaded it may work the first time an image is uploaded but it does not work if the user were to press the editImage button a second time and upload another image.
What is it that is being done wrong? Let me know if there is anything else that I can supply.
Thanks.
As I can see here, you are getting a URL back as the result of the profilePhoto. So you might as well use the AFNetworking function:
Im presuming photo is a UIImageView.
[photo setImageWithURL:[NSURL URLWithString:profPic] placeholderImage:[UIImage imageNamed:#"somePlaceholderImage"]];
The way I have my program working is it pulls data down into the program via AFHTTPClient. Then I get my response data. I then take this data and parse it into a NSMutableArray via NSJSONSerialization. This array is used to populate a UIPickerView.
This method fires when the user opens the app or presses a refresh button. The problem is when the app opened, the call is made and I get the data back. If I go to the picker it seems empty but when you scroll down the bottom 2 of 5 are in there and when you scroll back up the others get in too. If at any point I press the refresh button the errors go away and the picker is properly populated. Any reason why it is not working properly? I reloadAllComponents after each call is made too.
-(void) getData{
// Paramaters
NSString *lat = #"40.435615";
NSString *lng = #"-79.987872";
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: lat, #"lat", lng, #"lng", nil];
// posting the data and getting the response
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://mysite.com/"]];
[client postPath:#"/mypostpath.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *text = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#", text);
NSError *error;
json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
// setting the first location to the text feild
NSDictionary* name = [json objectAtIndex:0];
locationField.text = [name objectForKey:#"name"];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", [error localizedDescription]);
}];
// reload the picker
[pickerCust reloadAllComponents];
// setting the first location to the text feild
NSDictionary* name = [json objectAtIndex:0];
locationField.text = [name objectForKey:#"name"];
}
The problem is because the [pickerCust reloadAllComponents]; is being called before the block that loads the data is finished. Move the call into the success block.
Since it interacts with a UI component, wrap it in an dispatch_async so it runs on the main queue.
dispatch_async(dispatch_get_main_queue(), ^{
[pickerCust reloadAllComponents];
});
I'm putting the finishing touches on my own version of the heroku rails mobile iOS photo sharing app. I have implemented and successfully sent POST and GET requests via HTTP on iOS. Unfortunately, the Heroku tutorial explicitly states it won;t be going into how to write the DELETE request. Here's what I have so far:
+ (void)deletePhoto:(NSString *)owner
image:(NSString *)recordId
block:(void (^)(Photo *, NSError *))block
{
NSMutableDictionary *mutableParameters = [NSMutableDictionary dictionary];
[mutableParameters setObject:recordId forKey:#"photo[id]"];
NSLog(#"Destroying %#", recordId);
[[CloudGlyphAPIClient sharedClient] deletePath:#"/photo" parameters:mutableParameters success:^(AFHTTPRequestOperation *operation, id JSON) {
if (block) {
NSLog(#"DELETE sussessful");
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (block) {
block(nil, error);
}
}];
}
+ (void)getPhotos:(NSString *)owner
block:(void (^)(NSSet *photos, NSError *error))block
{
NSMutableDictionary *mutableParameters = [NSMutableDictionary dictionary];
[mutableParameters setObject:owner forKey:#"photo[owner]"];
[[CloudGlyphAPIClient sharedClient] getPath:#"/photos" parameters:mutableParameters success:^(AFHTTPRequestOperation *operation, id JSON) {
NSMutableSet *mutablePhotos = [NSMutableSet set];
for (NSDictionary *attributes in [JSON valueForKeyPath:#"photos"]) {
Photo *photo = [[Photo alloc] initWithAttributes:attributes];
[mutablePhotos addObject:photo];
}
if (block) {
block([NSSet setWithSet:mutablePhotos], nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (block) {
block(nil, error);
}
}];
}
I've based the DELETE request off of the GET request, except in this case we are looking for a particular image user a certain owner. I get an error that the routes file doesn't contain a path for DELETE /photos... i added the destroy method to the rails app and raked the routes.rb file.
I feel like this is a rails GOTCHA somewhere.. thanks for your help ^_^
TL;DR trying to write DELETE request for a rails app with AFNetworking
In AFNetworking, the DELETE path is a url path like this: photos/18.json is the record marked for removal. Found the answer over here:
Answer
Effectively, one can concat together a string to the url of the ActiveREcord in a table.