Search code examples
xcodefacebookuiimageprofilefacebook-ios-sdk

FBProfilePictureView - Save UIImage to UserDefaults


How do I get the UIImage out from the FBProfilePictureView? I couldn't find a post that explained it properly so check out my answer below and feel free to edit it!


Solution

  • So this was a question I was looking for on here the other day but couldn't find a correct answer that worked so I thought I'd answer my own for the community. Here goes:

    You will need to have already setup a login button with the:

    - (void)fbMethodLoggedInWithFbUser:(id<FBGraphUser>)user
    

    delegate method already working.

    We'll use a login screen with a 'Continue' button after loggin=Success to capture the UIImage, so add a "Continue" button (for pushing to the next screen after login) onto your storyboard and also a View with the class of "FBProfilePictureView" which is linked to the header file like so:

    @property (strong, nonatomic) IBOutlet FBProfilePictureView *userProfilePic;
    

    Then synthesise it in the .m file like so:

    @synthesise userProfilePic;
    

    Then set the Delegate in ViewDidLoad like so:

    - (void)viewDidLoad {
        [userProfilePic setDelegate:self];
    }
    

    Now we want to add this line anywhere in the .m file (make sure it's not nested inside a function!)

    id<FBGraphUser>cachedUser;
    

    Inside the Delegate method we mentioned earlier (fbMethodLoggedInWithFbUser) we will set our newly created id tag to equal the passthrough value of the delegate method like so:

    - (void)fbMethodLoggedInWithFbUser:(id<FBGraphUser>)user {
        cachedUser = user;
    
        // other login methods go here
    
    }
    

    Now your user is logged in, we have a cache of the '' id. The reason that this works best with a 'Continue' button after the user has logged in, is because the code I'm going to post will fetch the default blank profile picture image that Facebook uses as a temp image until the users profile picture loads. So to make sure this doesn't happen, first add in these 2 methods, then we will link the first up to the 'Continue' button action:

    - (void)getProfilePictureWithFbUser:(id<FBGraphUser>)user {
        userProfilePic.profileID = user.id;
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.4f];
        [userProfilePic setAlpha:1];
        [UIView commitAnimations];
    
        // -----------------------
        // CATCH PROFILE PICTURE::
    
        for (id obj in userProfilePic.subviews) {
            if ([obj isKindOfClass:[UIImageView class]]) {
                UIImageView *tempImageView = obj;
                UIImage *tempImage = tempImageView.image;
                [self saveImageToUDWithImage:tempImage];
            }
        }
    
    }
    

    This method is to save our captured UIImage from the 'userProfilePic' view to the UserDefaults:

    - (void)saveImageWithUDWithImage:(UIImage *)tempImage {
    
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        [ud setObject:UIImagePNGRepresentation(tempImage) forKey:@"userProfilePicture"];
        [ud synchronize];
    
    }
    

    Now set up your continue button like so:

    - (IBAction)continueButtonActionAfterLogin:(id)sender {
    
        // First we capture the user profile pic
        // with the cached id we got earlier after
        // login:
    
        [self captureProfilePicWithFBUser:cachedUser];
    
        // You can execute model pushes here, etc...
    
    }
    

    Then to read the UIImage from the UserDefaults later on, use this method:

    - (UIImage *)loadProfilePicFromUserDefaults {
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        NSData *imageData = [[NSUserDefaults standardUserDefaults] objectForKey:@"userProfilePicture"];
        UIImage *image = [UIImage imageWithData:imageData];
        return image;
    }
    

    This can be called in any other class that you want to display the user profile picture in like so:

    - (void)viewDidLoad {
    
        [myWantingToBeProfilePicture setImage:[self loadProfilePicFromUserDefaults];
    
    }
    

    Sorry for code being allover the place, but I've explained it in a way that made it clear to me, I just hope it's clear to everyone else too! Feel free to edit it and make it better!

    @Declanland