I am attempting to get a Users' saved data in CloudKit. I can see the record in the CloudKit Dashboard, but am unable to get to it via code in app.
-(void)getUserRecordID {
CKContainer *defaultContainer =[CKContainer defaultContainer];
[defaultContainer fetchUserRecordIDWithCompletionHandler:^(CKRecordID *recordID, NSError *error) {
if (!error) {
[defaultContainer fetchUserRecordIDWithCompletionHandler:^(CKRecordID *recordID, NSError *error) {
self.userRecordID = recordID;
NSLog(#"user record id: %#",recordID);
[self getUserRecord];
}];
}
else {
NSLog(#"error: %#",error.localizedDescription);
}
}];
}
-(void)getUserRecord {
CKContainer *defaultContainer =[CKContainer defaultContainer];
CKDatabase *publicDatabase = defaultContainer.publicCloudDatabase;
[publicDatabase fetchRecordWithID:self.userRecordID completionHandler:^(CKRecord *userRecord, NSError *error) {
if (!error) {
NSLog(#"current coins: %#",userRecord);
}
else {
NSLog(#"error: %#",error.localizedDescription);
}
}];
}
This gets me the User record information, but not the ID's of the saved private records. How can I get them?
Figured out the solution. You have to query for private records using CKQuery and NSPredicate.
-(void)getUserRecordID {
CKContainer *defaultContainer =[CKContainer defaultContainer];
[defaultContainer fetchUserRecordIDWithCompletionHandler:^(CKRecordID *recordID, NSError *error) {
if (!error) {
self.userRecordID = recordID;
NSLog(#"user record id: %#",recordID.recordName);
[self getStatsRecord];
}
else {
NSLog(#"error: %#",error.localizedDescription);
}
}];
}
-(void)getStatsRecord {
CKDatabase *privateDatabase = [[CKContainer defaultContainer] privateCloudDatabase];
CKReference *reference = [[CKReference alloc] initWithRecordID:self.userRecordID action:CKReferenceActionNone];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"creatorUserRecordID = %#", reference];
CKQuery *query = [[CKQuery alloc] initWithRecordType:#"Stats" predicate:predicate];
[privateDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
if (error) {
NSLog(#"error: %#",error.localizedDescription);
}
else {
if (![results firstObject]) {
[self createBlankRecord];
}
else {
CKRecord *record = [results firstObject];
NSLog(#"%#",record);
}
}
}];
}
Related
I need help posting a picture onto a tableview after i posted to parse. I am using parse and objective-c. I got to where you can post a picture and I can see it on parse, but how can I see the picture on like a timeline in my app or a table view?
Here is my code for posting to parse,
- (IBAction)uploadButton:(id)sender{
NSData* data = UIImageJPEGRepresentation(_imageView.image, 100);
PFFile *imageFile = [PFFile fileWithName:#"Image.jpg" data:data];
// Save the image to Parse
[imageFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
// The image has now been uploaded to Parse. Associate it with a new object
PFObject* newPhotoObject = [PFObject objectWithClassName:#"PhotoObject"];
[newPhotoObject setObject:imageFile forKey:#"image"];
[newPhotoObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
NSLog(#"Saved");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Success" message:#"Your picture has been successfully uploaded." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
else{
// Error
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
}];
}
What else do I need to put in order to see what I posted on my main tableview page?
I labeled the view controllers "posting page" and the "main page". The "main page" is where I want all the pictures I post to parse to end up, with a comment section for the picture.
i have done like this , may be useful to you. take a look
-(IBAction)btnUpDateImageClicked:(id)sender
{
if (UserSelectedImage)
{
HUDSHOWWITHTEXT(#"Updating profile");
PFQuery *query = [PFQuery queryWithClassName:User_Info];
NSLog(#"->%#",[PFUser currentUser].username);
[query whereKey:UserName equalTo:[PFUser currentUser].username];
[query getFirstObjectInBackgroundWithBlock:^(PFObject * user , NSError *error) {
if (!error) {
// Found User and modify it
PFFile *imageFile1,*imageFilePlaceHolder;
NSData *imageData1,*imageDataPlaceHolder;
// PFFile *fileDeleted = [[PFFile alloc] init];
if (UserSelectedImage) {
//User image
imageData1 = UIImageJPEGRepresentation(UserSelectedImage, 1.0);
imageFile1 = [PFFile fileWithName:#"img.png" data:imageData1];
[user setObject:imageFile1 forKey:#"user_image"];
//PlaceHolder
UIImage *imagPlaceholder = UserSelectedImage;
imagPlaceholder = [APP_DELEGATE SyncPlaceHolderImage:imagPlaceholder];
imageDataPlaceHolder = UIImageJPEGRepresentation(imagPlaceholder, 1.0);
imageFilePlaceHolder = [PFFile fileWithName:#"img.png" data:imageDataPlaceHolder];
[user setObject:imageFilePlaceHolder forKey:#"placeholder_image"];
}
else {
user[#"user_image1"] = [NSNull null];
user[#"placeholder_image"] = [NSNull null];
}
// Save
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
HUDHIDE;
if (UserSelectedImage) {
APP_DELEGATE.user.pfImageOne = imageFile1;
APP_DELEGATE.user.pfImagePlaceHolder= imageFilePlaceHolder;
}
else {
APP_DELEGATE.user.pfImageOne = nil;
APP_DELEGATE.user.pfImagePlaceHolder=nil;
}
ShowAlert(#"Saved SUccesfully");
}
else
{
HUDHIDE;
ShowAlert(#"Problem updating profile-%#");
}
}];
} else {
// Did not find any UserStats for the current user
NSLog(#"Error: %#", error);
HUDHIDE;
ShowAlert(#"Problem updating profile")
}
}];
}
else
{
ShowAlert(#"please select Image");
}
}
My requirement is to register for any one of the Health data like steps, weight, heart rate, etc., for background delivery using enableBackgroundDeliveryForType: method. And then create a Observer query for the same Health data to check.
In this scenario, if my application is killed by the user forcely and did changes to Health data using Health app. By this stage is it possible to get the notification to My application?
Is it mandatory to register for any of the background modes, to get notified for health data modifications through HKObserverQuery?
EDIT 1:
- (void)requestAuthorizationToShareTypes:(NSSet *)typesToShare readTypes:(NSSet *)typesToRead completion:(void (^)(BOOL, NSError *))completion
{
if ([HKHealthStore isHealthDataAvailable]) {
[self.healthStore requestAuthorizationToShareTypes:typesToShare readTypes:typesToRead completion:^(BOOL success, NSError *error) {
if(success)
{
self.authorizationSuccess = YES;
completion(YES, nil);
}
else
{
[MyUtilities showAlertWithTitle:#"Authorization fail!" message:#"You didn't allow to access Health data."];
completion(NO, error);
return;
}
}];
}
else
{
[MyUtilities showAlertWithTitle:#"Sorry!" message:#"Your device does not support Health data."];
NSDictionary *errorDictionary = #{ NSLocalizedDescriptionKey : #"Your device doesn't support Health Kit."};
NSError *error = [[NSError alloc] initWithDomain:#"" code:2 userInfo:errorDictionary];
completion(NO, error);
return;
}
}
- (void)authorizeConsumeHealth:(void (^)(BOOL, NSError *))completion
{
NSSet *readObjectTypes = [NSSet setWithObjects:
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryCaffeine],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryCalcium],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryChloride],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryIron],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureSystolic],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureDiastolic], [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount],
nil];
[self requestAuthorizationToShareTypes:nil readTypes:readObjectTypes completion:^(BOOL success, NSError *error) {
if(completion)
{
completion(success, error);
[self observeStepCountChanges];
}
}];
}
- (void)observeStepCountChanges
{
HKSampleType *sampleType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
[self.healthStore enableBackgroundDeliveryForType:sampleType frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError *error) {}];
HKObserverQuery *query = [[HKObserverQuery alloc] initWithSampleType:sampleType predicate:nil updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error) {
if(error)
{
NSLog(#"Steps count observer completion block. Error: %#", error);
}
else
{
NSLog(#"Steps count observer completion block");
}
}];
[self.healthStore executeQuery:query];
}
Please help me. Thanks.
I am newbie in Facebook Log in and i know this question asked many times but i not get solution at Please help me For this.
I create an app that contain Login With Facebook and it is Working As i want but when Application was Launch Then in my viewDidLoad method i Write a Code like as
- (void)viewDidLoad
{
self.qpinname=[[NSMutableArray alloc]init];
self.address=[[NSMutableArray alloc]init];
self.qpinType=[[NSMutableArray alloc]init];
[super viewDidLoad];
self.fbLogin.readPermissions = #[#"public_profile", #"email", #"user_friends"];
self.fbLogin.delegate=self;
[self.view addSubview:self.fbLogin];
[self.view addSubview:self.personalTable];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
if (FBSession.activeSession.isOpen)
{
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error)
{
self.username=user.name;
}
}];
NSLog(#"Session Is Open");
self.personalTable.hidden=FALSE;
[self connectWithFacebook];
}
else
{
NSLog(#"Session Is not open");
}
}
- (void)connectWithFacebook
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate openSessionWithAllowLoginUI:YES];
}
And My App Delegate Method I write a Method openSessionWithAllowLoginUI like as
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
NSArray *permissions = #[#"public_profile", #"email", #"user_friends"];
return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if (error)
{
NSLog (#"Handle error %#", error.localizedDescription);
}
else
{
[self checkSessionState:state];
}
}];
}
- (void) checkSessionState:(FBSessionState)state {
switch (state)
{
case FBSessionStateOpen:
{
RequestViewController *request=[[RequestViewController alloc]initWithNibName:#"RequestViewController"bundle:nil];
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error)
{
request.username=user.name;
NSLog(#"User Name %#",request.username);
PFQuery *query = [PFQuery queryWithClassName:#"MapInfo"];
if (request.username.length !=0)
{
[query whereKey:#"Admin" equalTo:request.username];
[query whereKey:#"Type" equalTo:#"Personal"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (!error)
{
request.address=[objects valueForKey:#"Address"];
request.qpinType=[objects valueForKey:#"Name"];
request.qpinname=[objects valueForKey:#"Type"];
request.locationDictionary=[objects valueForKey:#"Location"];
request.latitude=[request.locationDictionary valueForKey:#"lat"];
request.longitude=[request.locationDictionary valueForKey:#"lng"];
NSLog(#"Self.Qpin Name %# %#",request.latitude,request.longitude);
request.personalTable.hidden=FALSE;
dispatch_async(dispatch_get_main_queue(), ^{
[request.personalTable reloadData];
});
}
else
{
NSString *errorString = [[error userInfo] objectForKey:#"error"];
NSLog(#"Error: %#", errorString);
[request.personalTable reloadData];
}
}];
}
}
}];
}
break;
case FBSessionStateCreated:
break;
case FBSessionStateCreatedOpening:
break;
case FBSessionStateCreatedTokenLoaded:
break;
case FBSessionStateOpenTokenExtended:
break;
case FBSessionStateClosed:
break;
case FBSessionStateClosedLoginFailed:
break;
default:
break;
}
}
Then I get array Data at login as i want but it is Not Display in my TableView and in my Tableview View Controller I write a Code for viewWillAppear method like as
-(void)viewWillAppear:(BOOL)animated
{
if (FBSession.activeSession.state == FBSessionStateOpen
|| FBSession.activeSession.state == FBSessionStateOpenTokenExtended)
{
PFQuery *query = [PFQuery queryWithClassName:#"MapInfo"];
if (self.username.length !=0)
{
[query whereKey:#"Admin" equalTo:self.username];
[query whereKey:#"Type" equalTo:#"Personal"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (!error)
{
self.address=[objects valueForKey:#"Address"];
self.qpinType=[objects valueForKey:#"Name"];
self.qpinname=[objects valueForKey:#"Type"];
self.locationDictionary=[objects valueForKey:#"Location"];
self.latitude=[self.locationDictionary valueForKey:#"lat"];
self.longitude=[self.locationDictionary valueForKey:#"lng"];
NSLog(#"Self.Qpin Name %# %#",self.latitude,self.longitude);
[self.personalTable reloadData];
}
else
{
NSString *errorString = [[error userInfo] objectForKey:#"error"];
NSLog(#"Error: %#", errorString);
}
}];
}
}
else
{
self.username=#"";
}
}
Then it Display Data at when my ViewWillAppear but i want data at my Application launch Please Give me Solution For this.
Thanks.
I am having a very hard time here. There is one part in my application that STTwitter is successful and there is another part (using the same code) that does not return anything.
The part that does NOT work: `
-(IBAction)followTwitter:(id)sender {
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"twitter_on_file" ] == nil) {
UIAlertView *allert = [[UIAlertView alloc] initWithTitle:#"Uh oh!" message:#"You have not linked your twitter account quite yet! Head to My Account settins to do so." delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil, nil];
[allert show];
} else {
ACAccountStore *store1 = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType = [store1 accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
if ([twitterAccountType accessGranted]) {
[store1 requestAccessToAccountsWithType:twitterAccountType options:nil completion:^(BOOL granted, NSError *error) {
arrayOfUsernames = [[NSMutableArray alloc] init];
iosAccounts = [store1 accountsWithAccountType:twitterAccountType];
for (ACAccount *accou in iosAccounts) {
[arrayOfUsernames addObject:accou.username];
}
NSString *usernameOnFile = [[NSUserDefaults standardUserDefaults] objectForKey:#"twitter_on_file" ];
int tracker = 0;
for (NSString *username in arrayOfUsernames) {
if ([username isEqualToString:usernameOnFile]) {
NSLog(#"Using twitter account: %#", username);
STTwitterAPI *twitterAPI = [STTwitterAPI twitterAPIOSWithAccount:iosAccounts[tracker]];
[twitterAPI verifyCredentialsWithSuccessBlock:^(NSString *username) {
NSLog(#"Successfully authenticated the user");
} errorBlock:^(NSError *error) {
NSLog(#"Erorr: %#", error);
}];
NSLog(#"Twitter API: %#", twitterAPI);
[twitterAPI postFriendshipsCreateForScreenName:#"kickscaterer" orUserID:nil successBlock:^(NSDictionary *befriendedUser) {
NSLog(#"Befriend %#", befriendedUser);
} errorBlock:^(NSError *error) {
NSLog(#"Error: %#", error);
}];
} else {
tracker++;
}
}
}];
}
}
}
`
The part that DOES work:
STTwitterAPI *twitter= [STTwitterAPI twitterAPIOSWithAccount:iosAccounts[indexForAlert.row]];
[twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
// ...
NSLog(#"Username: %#", username);
// [self.tableView reloadData];
[[NSUserDefaults standardUserDefaults] setObject:twitter.userName forKey:#"twitter_on_file"];
} errorBlock:^(NSError *error) {
NSLog(#"Error: %#", error);
// ...
}];
[twitter postFriendshipsCreateForScreenName:#"didi4" orUserID:nil successBlock:^(NSDictionary *befriendedUser) {
NSLog(#"Befriend %#", befriendedUser);
} errorBlock:^(NSError *error) {
NSLog(#"Error: %#", error);
}];
Thanks!
The postFriendshipsCreateForScreenName: method should be called inside the success block, at the same level than the log "Successfully authenticated the user".
I'm retrieving data from my parse database and looping it into an NSMutableArray. This is in my getHomes method, which is being called in viewDidLoad. The NSMutableArray contain various UIImages, which CGSize' i'm looping through. This method is called getCellHeights. I want to call this method right after the getHomes method, but stacking them like this in viewdidLoad does not do the trick. The getCellHeights method is not running since there is no objects in the NSMutableArray, cause its not completed with the retrieving of data.
How can i make sure that the getCellHeights is not running before the getHomes method is completed?
getCellHeights
-(void)getcellHeights {
for (int i = 0; i < homesDic.count; i++) {
UIImage *image = [[homesDic objectAtIndex:i] objectForKey:#"image"];
CGFloat divider = image.size.width/145;
CGFloat wantedWidth = 145;
CGFloat wantedHeight = image.size.height/divider;
NSLog(#"width: %f height: %f", wantedWidth, wantedHeight);
CGSize size = CGSizeMake(wantedWidth, wantedHeight);
[_cellSizes addObject:[NSValue valueWithCGSize:size]];
}
}
getHomes
-(void)getHomes {
PFQuery *query = [PFQuery queryWithClassName:#"Homes"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects1, NSError *error) {
if (!error) {
for (PFObject *object in objects1) {
PFQuery *userQ = [PFUser query];
[userQ getObjectInBackgroundWithId:[object objectForKey:#"userId"] block:^(PFObject *userName, NSError *error) {
NSLog(#"%#", userName);
[[userName objectForKey:#"file"] getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
UIImage *profileImage = [UIImage imageWithData:data];
PFQuery *homeQ = [PFQuery queryWithClassName:#"homeImages"];
[homeQ whereKey:#"homeId" equalTo:object.objectId];
[homeQ whereKey:#"number" equalTo:#(0)];
[homeQ findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
PFQuery *cityQ = [PFQuery queryWithClassName:#"City"];
id zip = [NSNumber numberWithInteger: [[object objectForKey:#"zip"] intValue]];
[cityQ whereKey:#"fra" greaterThanOrEqualTo:zip];
[cityQ whereKey:#"fra" lessThanOrEqualTo:zip];
[cityQ findObjectsInBackgroundWithBlock:^(NSArray *cObject, NSError *error) {
if (!error) {
PFObject *cityObject = [cObject lastObject];
PFObject *image = [objects lastObject];
[[image objectForKey:#"Image"] getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
UIImage *image = [UIImage imageWithData:data];
NSMutableDictionary *flagDict = [[NSMutableDictionary alloc] init];
[flagDict setObject:[object objectForKey:#"title"] forKey:#"title"];
[flagDict setObject:image forKey:#"image"];
[flagDict setObject:[cityObject objectForKey:#"navn"] forKey:#"city"];
[flagDict setObject:[userName objectForKey:#"name"] forKey:#"name"];
[flagDict setObject:profileImage forKey:#"profileImage"];
[homesDic addObject:flagDict];
[self.collectionView reloadData];
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
}];
}
}];
}];
}];
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
The Blocks that you're passing to the Parse framework query methods are completion/callback Blocks; when the fetch has completed, they are run. Do whatever you need to do after the fetch -- including calling cellHeights -- in the appropriate completion Block.