I'm getting values from Parse Cloud by pressing a button. The code for getting the data data from Parse is in another class, but when I try to show the MBProgessHUD from that class it doesn't do anything.
No errors either. However, if I do all in the same class, it works. Not sure how to display the progressHUD from another class on a specific view which is open at that time.
- (IBAction)testWeather:(id)sender {
Reports * obje2 = [[Reports alloc]init];
[obje2 startGetting];
}
// in reports class
-(void) startGetting {
Names= [[NSMutableArray alloc] init];
Latitude= [[NSMutableArray alloc] init];
Longitude= [[NSMutableArray alloc] init];
[Names removeAllObjects];
[Latitude removeAllObjects];
[Longitude removeAllObjects];
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *CountyName = [standardUserDefaults stringForKey:#"CurrentlySelectedCounty"];
PFQuery *query = [PFQuery queryWithClassName:#"Reports"];
[query whereKey:#"County" equalTo:#"Universal"];
//
NSInteger countTotal= [query countObjects];
NSString *totalVals = [NSString stringWithFormat: #"%d", (int)countTotal];
[[NSUserDefaults standardUserDefaults] setObject:totalVals forKey:#"NumberOfSwamps"];
//
NSString * storyboardName = #"Main_iPhone";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"browsePage"];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:vc.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = #"Loading Reports";
[hud show:YES];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
[hud hide:YES];
if (!error) {
for (PFObject *obj in objects) {
NSString *LastName = [obj objectForKey:#"Name"] ;
NSString *Lat = [obj objectForKey:#"Latitude"] ;
NSString *Lon = [obj objectForKey:#"Longitude"] ;
// add values to array
[Names addObject:LastName];
[Latitude addObject:Lat];
[Longitude addObject:Lon];
[self getResults];
}
}
else{
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
Trying another way...but this doesn't work either...even though HUD is running from the original class.
browse.m,
if (myInt == 8){
NSLog(#"\n \n Pressed the refresh icon for reports");
[self removeAllAnnotations];
[standardUserDefaults setInteger:1 forKey:#"HUD_Switch"]; // to make sure switching on
[standardUserDefaults synchronize];
[self HUDSwitcher];
Reports * obje2 = [[Reports alloc]init];
[obje2 startGetting];
}
-(void) HUDSwitcher{
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSInteger myInt = [standardUserDefaults integerForKey:#"HUD_Switch"]; // 0 for switched off .... 1 for switched on
NSString * storyboardName = #"Main_iPhone";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"browsePage"];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:vc.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = #"Testing";
[hud show:YES];
if (myInt==0) {
[hud hide:YES];
}
}
reports.m
[standardUserDefaults setInteger:1 forKey:#"HUD_Switch"]; // to switch on the HUD value
browsePage * obje2 = [[browsePage alloc]init];
[obje2 HUDSwitcher];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
[standardUserDefaults setInteger:0 forKey:#"HUD_Switch"];
[standardUserDefaults synchronize];
browsePage * obje2 = [[browsePage alloc]init];
[obje2 HUDSwitcher];
if (!error) {
for (PFObject *obj in objects) {
NSString *LastName = [obj objectForKey:#"Name"] ;
NSString *Lat = [obj objectForKey:#"Latitude"] ;
NSString *Lon = [obj objectForKey:#"Longitude"] ;
// add values to array
[Names addObject:LastName];
[Latitude addObject:Lat];
[Longitude addObject:Lon];
[self getResults];
}
}
else{
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
When you instantiate the new UIViewController vc, it is not in the current view stack, so if you display a progressHUD on its view it won't appear on the screen.
You should display the progressHUD from the view of the initial viewController.
One way to solve this would be with delegation like this:
- (IBAction)testWeather:(id)sender {
self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = #"Loading Reports";
[hud show:YES];
Reports * obje2 = [[Reports alloc]init];
[obje2 startGettingWithDelegate:self];
}
- (void)reports:(Reports*)report didFinishGetting
{
[self.hud hide:YES];
}
In yourViewController interface in the .h file add this:
#property (nonatomic, strong) MBProgressHUD *hud;
In Reports Class
-(void) startGettingWithDelegate:id<yourProtocol> delegate {
Names= [[NSMutableArray alloc] init];
Latitude= [[NSMutableArray alloc] init];
Longitude= [[NSMutableArray alloc] init];
[Names removeAllObjects];
[Latitude removeAllObjects];
[Longitude removeAllObjects];
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *CountyName = [standardUserDefaults stringForKey:#"CurrentlySelectedCounty"];
PFQuery *query = [PFQuery queryWithClassName:#"Reports"];
[query whereKey:#"County" equalTo:#"Universal"];
//
NSInteger countTotal= [query countObjects];
NSString *totalVals = [NSString stringWithFormat: #"%d", (int)countTotal];
[[NSUserDefaults standardUserDefaults] setObject:totalVals forKey:#"NumberOfSwamps"];
//
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
// Inform Delegate that finished loading
[delegate reports:self didFinishLoading];
if (!error) {
for (PFObject *obj in objects) {
NSString *LastName = [obj objectForKey:#"Name"] ;
NSString *Lat = [obj objectForKey:#"Latitude"] ;
NSString *Lon = [obj objectForKey:#"Longitude"] ;
// add values to array
[Names addObject:LastName];
[Latitude addObject:Lat];
[Longitude addObject:Lon];
[self getResults];
}
} else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
To do this right you should create a #protocol in Reports.h and make you viewController conform to it.
In Reports.h
#protocol ReportsProtocol
- (void)reports:(Reports*) finishedLoading;
#end
#interface ...
.
.
.
In yourViewController.h
#interface YourViewController : UIViewController <ReportsProtocol>
.
.
.
Another solution can be using blocks. Its a little more complicated but cleaner.
Related
I have one login screen after that it will move to next view controller which have i have used some networks like http,json to get data from server. when i enter login username/password then if i click login button its getting delay to 8 seconds after that only it moving to next view controller.Still that my login screen alone showing for 8 seconds and then only it move to next view controller.
Here my login controller.m:
#implementation mainViewController
- (void)viewDidLoad {
[super viewDidLoad];
_username.delegate = self;
_password.delegate = self;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults boolForKey:#"reg"]) {
NSLog(#"no user reg");
_logBtn.hidden = NO;
}
}
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
_username.text = nil;
_password.text = nil;
}
- (IBAction)LoginUser:(id)sender {
if ([_username.text isEqualToString:#"sat"] && [_password.text isEqualToString:#"123"]) {
NSLog(#"Login success");
[self performSegueWithIdentifier:#"nextscreen" sender:self];
}
else {
NSLog(#"login was unsucess");
// Alert message
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"wrong"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionOk = [UIAlertAction actionWithTitle:#"Ok"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:actionOk];
[self presentViewController:alertController animated:YES completion:nil];
}
}
Here my nextcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
//for search label data
self.dataSourceForSearchResult = [NSArray new];
//collection of array to store value
titleArray = [NSMutableArray array];
// here only i am getting data from server
[self getdata];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView reloadData];
}
Help me out. If my question din't understand.I can tell more about my post. And in my nextcontroller.m [self getdata] is i am getting data from server url.Thanks
My get data:
-(void)getdata {
NSString *userName = #“users”;
NSString *password = #“images”;
NSData *plainData = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainData base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
NSString *urlString = #"https://porterblog/image/file”;
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:0]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSError * error;
self->arrayPDFName = [[NSMutableArray alloc]init];
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *dictOriginal = jsonResults[#“birds”];
[titleArray addObject:[NSString stringWithFormat:#" birds(%#)”, dictOriginal[#"count"]]];
NSDictionary *dictOriginal2 = jsonResults[#"owl”];
[titleArray addObject:[NSString stringWithFormat:#" Owl(%#)”, dictOriginal2[#"count"]]];
NSDictionary *dictOriginal3 = jsonResults[#"pensq”];
[titleArray addObject:[NSString stringWithFormat:#" Pensq(%#)”, dictOriginal3[#"count"]]];
NSDictionary *dictOriginal4 = jsonResults[#“lion”];
[titleArray addObject:[NSString stringWithFormat:#" lion(%#)”, dictOriginal4[#"count"]]];
NSArray *arrayFiles = [NSArray arrayWithObjects: dictOriginal, dictOriginal2, dictOriginal3, dictOriginal4, nil];
NSLog(#"str: %#", titleArray);
for (NSDictionary *dict in arrayFiles) {
NSMutableArray *arr = [NSMutableArray array];
NSArray *a = dict[#"files"];
for(int i=0; i < a.count; i ++) {
NSString *strName = [NSString stringWithFormat:#"%#",[[dict[#"files"] objectAtIndex:i] valueForKey:#"name"]];
[arr addObject:strName];
}
[arrayPDFName addObject:arr];
}
NSString *errorDesc;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory1 stringByAppendingPathComponent:#"SampleData.plist"];
NSString *error1;
returnData = [ NSPropertyListSerialization dataWithPropertyList:jsonResults format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
if(returnData ) {
if ([returnData writeToFile:plistPath atomically:YES]) {
NSLog(#"Data successfully saved.");
}else {
NSLog(#"Did not managed to save NSData.");
}
}
else {
NSLog(#"%#",errorDesc);
}
NSDictionary *stringsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
}
EDITED:
`- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
self.dataSourceForSearchResult = [NSArray new];
titleArray = [NSMutableArray array];
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView reloadData];
self.navigationItem.hidesBackButton = YES;
});
});
}`
You're getting your data using main thread you need do to that in background then invoke the code you need (as i see is reload collectionView)
I assume that because you didn't show the getdata method code
If that the case you can use this code:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[self.collectionView reloadData];
});
});
It's mean that your VC will show immediately but the collectionView fill after you finish load the data, you can put some old data while loading like Facebook app (you see latest retrieved posts until finish loading].
Edit:
In your code you replace viewdidload method in nextController with next code:
- (void)viewDidLoad {
[super viewDidLoad];
//for search label data
self.dataSourceForSearchResult = [NSArray new];
//collection of array to store value
titleArray = [NSMutableArray array];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[self.collectionView reloadData];
});
});
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
}
I'm using the below code in my ViewController.m to log a user in to my app. However on the following ViewController (AccountViewController), I have a tableView. Upon successful login, I want to reload/populate the data in the tableView, but instead after a successful login, I get an empty table. I've put reloadData in viewWillAppear at the top of MyAccountViewController. See below. Not sure why it's doing this, as when I navigate from AccountViewController to another screen and back, the table is populated. Is my AFNetworking bit causing the table not to populate for some reason?
ViewController.m
[DIOSUser userLoginWithUsername:_userField.text
andPassword:_passField.text
success:^(AFHTTPRequestOperation *op, id response) {
// Saving to keychain/NSUserDefaults
NSDictionary *diosSession = [[DIOSSession sharedSession] user];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:diosSession] forKey:#"diosSession"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[DIOSSession sharedSession] getCSRFTokenWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *csrfToken = [NSString stringWithUTF8String:[responseObject bytes]];
[[NSUserDefaults standardUserDefaults] setObject:csrfToken forKey:#"diosToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// failure handler
}];
wrongLogin.hidden = YES;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MyAccountViewController *yourViewController = (MyAccountViewController *)[storyboard instantiateViewControllerWithIdentifier:#"MyAccount"];
[self.navigationController pushViewController:yourViewController animated:YES];
[self.activityIndicatorViewOne stopAnimating];
self.activityIndicatorViewOne.hidden = YES;
NSLog(#"Success!");}
failure:^(AFHTTPRequestOperation *op, NSError *err) { NSLog(#"Fail!"); wrongLogin.hidden = NO; }
];
AccountViewController.m
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView reloadData];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(ReloadDataFunction:)
name:#"refresh"
object:nil];
[self.tableView reloadData];
self.descripData = [[NSMutableArray alloc] init];
UIBarButtonItem *flipButton = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:#"logouticon4.png"]
// initWithTitle:#"Logout"
style:UIBarButtonItemStylePlain
target:self
action:#selector(flipView)];
self.navigationItem.rightBarButtonItem = flipButton;
[flipButton release];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
[self.navigationItem setHidesBackButton:YES animated:YES];
refreshControl = [[UIRefreshControl alloc]init];
[self.tableView addSubview:refreshControl];
[refreshControl addTarget:self action:#selector(refreshTable) forControlEvents:UIControlEventValueChanged];
// Do any additional setup after loading the view.
self.storageData = [[NSMutableDictionary alloc] init];
userName.text = [[[DIOSSession sharedSession] user] objectForKey:#"name"];
//emailAddress.text = [[[DIOSSession sharedSession] user] objectForKey:#"mail"];
NSLog(#"%#", [[DIOSSession sharedSession] user]);
// DIOSView *view = [[DIOSView alloc] init];
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"storeditems" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.descripData = [responseObject mutableCopy];
NSLog(#"%#",self.descripData);
// [self.tableView reloadData];
// [HUD hide:YES];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
[DIOSNode nodeIndexWithPage:#"0" fields:#"title" parameters:[NSArray arrayWithObjects:#"storage_item", nil] pageSize:#"20" success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Nodes retrieved!");
__block int iCount = 0;
for (id object in responseObject) {
// NSLog(#"adding object!");
[self.storageData setObject:(NSDictionary *)object forKey:[NSString stringWithFormat:#"%d",iCount]];
iCount++;
[self.tableView reloadData];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([self.storageData count] > 0 && self.descripData.count > 0)
{
return [self.descripData count];
}
else
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DoctorsTableIdentifier = #"StorageItemTableViewCell";
StorageItemTableViewCell *cell = (StorageItemTableViewCell *)[tableView dequeueReusableCellWithIdentifier:DoctorsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StorageItemTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (self.storageData.count > 0 && self.descripData.count > 0) {
noitemsView.hidden = YES;
cell.cellCountLabel.text = [NSString stringWithFormat:#"%i", indexPath.row+1];
NSDictionary *title = [self.descripData objectAtIndex:indexPath.row];
[[cell itemName] setText:[title objectForKey:#"node_title"]];
NSDictionary *node = [self.descripData objectAtIndex:indexPath.row];
[[cell itemDescrip] setText:[node objectForKey:#"body"]];
NSDictionary *value = [self.descripData objectAtIndex:indexPath.row];
[[cell valueLabel] setText:[value objectForKey:#"storeditemvalue"]];
NSLog(#"%#", self.descripData);
NSDictionary *quantity = [self.descripData objectAtIndex:indexPath.row];
[[cell quantityLabel] setText:[quantity objectForKey:#"numberofitemstored"]];
NSLog(#"%#", self.descripData);
NSString *secondLink = [[self.descripData objectAtIndex:indexPath.row] objectForKey:#"photo"];
[cell.itemPhoto sd_setImageWithURL:[NSURL URLWithString:secondLink]];
NSLog(#"%#",secondLink);
}
else {
noitemsView.hidden = NO;
}
return cell;
}
You have a "refresh" observer, but it calls a function you haven't shown here. You set your data it looks like with this:
for (id object in responseObject) {
// NSLog(#"adding object!");
[self.storageData setObject:(NSDictionary *)object forKey:[NSString stringWithFormat:#"%d",iCount]];
iCount++;
[self.tableView reloadData];
}
but because that is in viewDidLoad, it is only called once, BEFORE viewWillAppear. You need to fill self.storageData and self.descripData in a separate function, then call THAT function from viewWillAppear, or using your NSNotificationCenter notification from the previous VC.
I run a Parse query in my iOS app TableViewController.m.
I need to ask the iOS app for that query data from my WatchKit extension InterfaceController.m
How would I go about this using openParentApplication(_:reply:) + handleWatchKitExtensionRequest(_:reply:)?
TableViewController.m (iOS)
- (void)viewDidLoad {
// GMT Date from Phone
NSDate *gmtNow = [NSDate date];
NSLog(#"GMT Now: %#", gmtNow);
// Query Parse
PFQuery *query = [self queryForTable];
[query whereKey:#"dateGame" greaterThanOrEqualTo:gmtNow];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSMutableArray *localMatchup = [#[] mutableCopy];
for (PFObject *object in objects) {
// Add objects to local Arrays
[localMatchup addObject:[object objectForKey:#"matchup"]];
// App Group
NSString *container = #"group.com.me.off";
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:container];
// Matchup
[defaults setObject:localMatchup forKey:#"KeyMatchup"];
NSArray *savedMatchup = [defaults objectForKey:#"KeyMatchup"];
NSLog(#"Default Matchup: %#", savedMatchup);
savedMatchup = matchupArray;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
}];
}
AppDelegate.m (iOS)
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
NSString * request = [userInfo objectForKey:#"requestString"];
if ([request isEqualToString:#"executeMethodA"]) {
// GMT Date from Phone
NSDate *gmtNow = [NSDate date];
NSLog(#"GMT Now: %#", gmtNow);
// Query Parse
PFQuery *query = [self queryForTable];
[query whereKey:#"dateGame" greaterThanOrEqualTo:gmtNow];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSMutableArray *localMatchup = [#[] mutableCopy];
for (PFObject *object in objects) {
// Add objects to local Arrays
[localMatchup addObject:[object objectForKey:#"matchup"]];
// App Group
NSString *container = #"group.com.me.off";
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:container];
// Matchup
[defaults setObject:localMatchup forKey:#"KeyMatchup"];
NSArray *savedMatchup = [defaults objectForKey:#"KeyMatchup"];
NSLog(#"Default Matchup: %#", savedMatchup);
savedMatchup = matchupArray;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
reply(#{#"success:": #true});
}
}];
}
// Assuming this is where I'd do the reply?
// Not sure what would go here for the reply though?
reply(#{#"success:": #false});
}
InterfaceController.m (WatchKit)
NSString *requestString = [NSString stringWithFormat:#"executeMethodA"]; // This string is arbitrary, just must match here and at the iPhone side of the implementation.
NSDictionary *applicationData = [[NSDictionary alloc] initWithObjects:#[requestString] forKeys:#[#"theRequestString"]];
[WKInterfaceController openParentApplication:applicationData reply:^(NSDictionary *replyInfo, NSError *error) {
// What would I put here?
NSLog(#"\nReply info: %#\nError: %#",replyInfo, error);
}];
I'm using Objective-C. Will add any extra info needed, thanks!
Make the Parse query in your AppDelegate method and package it in an NSDictionary and call reply(queryDict); The replyInfo dictionary in your InterfaceController will be populated with queryDict.
I am quite new to iOS development so please be nice :) I am developing an app at the moment. A user will register by filling in a form which is just a bunch of TextFields.
Once the user registers they will be redirected to their homePage where a UIImageView and a UILabel will display there data they used when registering.
Now my issue is how to ensure that this UIImageView and UILabel display the same data everytime that same user logs in. I tried this using NSUserDefaults but when the user logs in it would display the users data that i just registered with. Any suggestions would be great and also I am using parse for my data base.
Here is the code for when a user registers
NSLog(#"Registering user");
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Registering";
PFObject *parent = [PFObject objectWithClassName:#"Parent"];
UIImage *image = form.profilePhoto;
NSData *imageData = UIImageJPEGRepresentation(image, 0.6);
PFFile *imageFile = [PFFile fileWithName:#"image.jpeg" data:imageData];
parent[#"Name"] = form.name;
parent[#"Email"] = form.email;
parent[#"Password"] = form.password;
parent[#"Location"] = form.location;
parent[#"ImageFile"] = imageFile;
[parent saveInBackground];
[parent saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
[hud hide:YES];
currentUser = YES;
//saveData to parentUser
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:form.name forKey:#"Name"];
//Send user to parent home page
PHomeViewController *lvc=[self.storyboard instantiateViewControllerWithIdentifier:#"Phome"];
SlideNavigationController *navcontroller = [[SlideNavigationController alloc] initWithRootViewController:lvc];
ParentMenu *leftMenu = (ParentMenu*)[self.storyboard instantiateViewControllerWithIdentifier: #"LeftMenuViewController"];
[self.navigationController pushViewController:lvc animated:YES];
navcontroller.leftMenu = leftMenu;
//save data to nsuserdefualts
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
UIImage *uploadPhoto = form.profilePhoto;
[defaults setObject:form.name forKey:#"Name"];
[defaults setObject:UIImageJPEGRepresentation(uploadPhoto, 0.6) forKey:#"ImageFile"];
[defaults synchronize];
NSLog(#"Data has been saved");
}
else {
NSLog(#"There was an error in registration");
}
}];
}
}
And this is the code that runs when a user logs in
(IBAction)login:(id)sender {
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Loading...";
PFQuery *query = [PFQuery queryWithClassName:#"Parent"];
[query whereKey:#"Email" equalTo:_Email.text];
[query whereKey:#"Password" equalTo:_Password.text];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (object) {
NSLog(#"User logged in successfully");
//Send user to parent home page
PHomeViewController *lvc=[self.storyboard instantiateViewControllerWithIdentifier:#"Phome"];
SlideNavigationController *navcontroller = [[SlideNavigationController alloc] initWithRootViewController:lvc];
ParentMenu *leftMenu = (ParentMenu*)[self.storyboard instantiateViewControllerWithIdentifier: #"LeftMenuViewController"];
[self.navigationController pushViewController:lvc animated:YES];
navcontroller.leftMenu = leftMenu;
} else {
// LOGIN ERROR
UIAlertView *ALERT = [[UIAlertView alloc]initWithTitle:#"Error" message:#"There was an error logging in please try again later." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[ALERT show];
_Email.text = [NSString stringWithFormat:#""];
_Password.text = [NSString stringWithFormat:#""];
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
}];
}
Thanks!
Hi I have tried some code for new user registration using XMPPFrameWork in IOS.
-(IBAction)Registaton:(id)sender
{
// iPhoneXMPPAppDelegate *appDelegate =(iPhoneXMPPAppDelegate *)[[UIApplication sharedApplication]delegate];
[[[self appDelegate] xmppStream] connectWithTimeout:XMPPStreamTimeoutNone error:nil];
NSString *username = self.username.text;
NSString *password = self.password.text;
NSString *name =self.name.text;
NSString *email=self.email.text;
NSMutableArray *elements = [NSMutableArray array];
[elements addObject:[NSXMLElement elementWithName:#"username" stringValue:username]];
[elements addObject:[NSXMLElement elementWithName:#"password" stringValue:password]];
[elements addObject:[NSXMLElement elementWithName:#"name" stringValue:name]];
[elements addObject:[NSXMLElement elementWithName:#"email" stringValue:email]];
[[[self appDelegate] xmppStream] registerWithElements:elements error:nil];
NSLog(#"Register ====%#",[[self appDelegate] xmppStream]);
//[[[self appDelegate] xmppStream] registerWithPassword:elements error:nil];
}
but through this method i am not able register on server. it gives me connecting to Xmppstream Please wait.. Can anyone help me how can i create a new account on server using XMPPFrameWork in ios.
Try this. Its works fine for me
- (void)updateAccountInfo
{
//NSString *domain = [[NSString alloc] initWithString:#"192.168.1.100"];
//int port = 5222;
NSString *usname =[[NSString alloc] initWithString:self.txtUsername.text];
NSString *juser =[[NSString alloc] initWithString:[usname stringByAppendingString:#"your server ip"]];
XMPPJID *jid = [XMPPJID jidWithString:juser];
[self xmppStream].myJID =jid;
allowSelfSignedCertificates = NSOnState;
allowSSLHostNameMismatch = NSOnState;
NSUserDefaults *dflts = [NSUserDefaults standardUserDefaults];
//[dflts setObject:domain forKey:#"Account.Server"];
// [dflts setObject:(port ? [NSNumber numberWithInt:port] : nil)
// forKey:#"Account.Port"];
[dflts setObject:juser
forKey:#"Account.JID"];
[dflts setObject:#"ios"
forKey:#"Account.Resource"];
[dflts setBool:useSSL forKey:#"Account.UseSSL"];
[dflts setBool:allowSelfSignedCertificates forKey:#"Account.AllowSelfSignedCert"];
[dflts setBool:allowSSLHostNameMismatch forKey:#"Account.AllowSSLHostNameMismatch"];
[dflts setBool:YES forKey:#"Account.RememberPassword"];
[dflts setObject:self.txtPasswd.text forKey:#"Account.Password"];
[dflts synchronize];
}
- (void)createAccount
{
[self updateAccountInfo];
NSError *error = nil;
BOOL success;
if(![[[self appDelegate] xmppStream] isConnected])
{
if (useSSL)
success = [[self xmppStream] oldSchoolSecureConnectWithTimeout:XMPPStreamTimeoutNone error:&error];
else
success = [[self xmppStream] connectWithTimeout:XMPPStreamTimeoutNone error:&error];
}
else
{
//NSString *password = [[NSString alloc] initWithString:#"321" ];
success = [[self xmppStream] registerWithPassword:self.txtPasswd.text error:&error];
}
if (success)
{
[self appDelegate].isRegistering = YES;
}
else
{
NSLog(#"not succeed ");
}
}
- (void)xmppStreamDidRegister:(XMPPStream *)sender{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Registration" message:#"Registration with XMPP Successful!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error{
DDXMLElement *errorXML = [error elementForName:#"error"];
NSString *errorCode = [[errorXML attributeForName:#"code"] stringValue];
NSString *regError = [NSString stringWithFormat:#"ERROR :- %#",error.description];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Registration with XMPP Failed!" message:regError delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
if([errorCode isEqualToString:#"409"]){
[alert setMessage:#"Username Already Exists!"];
}
[alert show];
}
A simple and WORKING approach which HAS WORKED for me
NSString *username = #"rohit#XMPP_SERVER_IP_HERE"; // OR [NSString stringWithFormat:#"%##%#",username,XMPP_BASE_URL]]
NSString *password = #"SOME_PASSWORD";
AppDelegate *del = (AppDelegate *)[[UIApplication sharedApplication] delegate];
del.xmppStream.myJID = [XMPPJID jidWithString:username];
NSLog(#"Does supports registration %ub ", );
NSLog(#"Attempting registration for username %#",del.xmppStream.myJID.bare);
if (del.xmppStream.supportsInBandRegistration) {
NSError *error = nil;
if (![del.xmppStream registerWithPassword:password error:&error])
{
NSLog(#"Oops, I forgot something: %#", error);
}else{
NSLog(#"No Error");
}
}
// You will get delegate called after registrations in either success or failure case. These delegates are in XMPPStream class
// - (void)xmppStreamDidRegister:(XMPPStream *)sender
//- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error