Parsing data with hpple then displaying in labels - parsing

So far I have this:
I am trying to parse date with hpple from a webpage and then display it in labels. I don't know how to go about this. I guess I have to make the Secret variable in the void GoToSecretsList somehow equal the values the other void is getting... does anyone have any suggestions?
- (void)GoToSecretsList
{
UIViewController *vc;
vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecretsListID"];
[self.navigationController pushViewController:vc animated:YES];
UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 120, 500, 40)];
[myLabel setBackgroundColor:[UIColor clearColor]];
NSString *Secret;
Secret = #"Get value from website";
[myLabel setText:[NSString stringWithFormat:#"#1: %#", Secret]];
[[vc view] addSubview:myLabel];
}
-(void)LoadSecrets {
// 1
NSURL *SecretsUrl = [NSURL URLWithString:#"http:/removed.com/xlxlx"];
NSData *SecretsHtmlData = [NSData dataWithContentsOfURL:SecretsUrl];
// 2
TFHpple *secretsParser = [TFHpple hppleWithHTMLData:SecretsHtmlData];
// 3
NSString *secretsXpathQueryString = #"/secret";
NSArray *secretsNodes = [secretsParser searchWithXPathQuery:secretsXpathQueryString];
// 4
NSMutableArray *newSecrets = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in secretsNodes) {
// 5
VOI *secret = [[VOI alloc] init];
[newSecrets addObject:secret];
// 6
secret.title = [[element firstChild] content];
// 7
secret.url = [element objectForKey:#"href"];
}
}
Edit: Now I just have this:
- (void)GoToSecretsList
{
UIViewController *vc;
vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecretsListID"];
[self.navigationController pushViewController:vc animated:YES];
UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 120, 500, 40)];
[myLabel setBackgroundColor:[UIColor clearColor]];
NSURL *SecretsUrl = [NSURL URLWithString:#"http://removed.com/dsdsds"];
NSData *SecretsHtmlData = [NSData dataWithContentsOfURL:SecretsUrl];
TFHpple *secretsParser = [TFHpple hppleWithHTMLData:SecretsHtmlData];
NSString *secretsXpathQueryString = #"/secret";
NSArray *secretsNodes = [secretsParser searchWithXPathQuery:secretsXpathQueryString];
[myLabel setText:[NSString stringWithFormat:#"#1: %#", secretsNodes]];
[[vc view] addSubview:myLabel];
}
But what variable has the information..? or what I am doing wrong? Because secretNodes isn't it.

Can you post some real html to help know what text you're looking for?
e.g. the following will get all the <h2></h2> nodes:
NSString *secretsXpathQueryString = #"//h2";//note double slashes for tag name
whereas this will get those with a specific class:
NSString *secretsXpathQueryString = #"//h2[#class='secret']";//note single quotes
Once you have the correct query, take a look at TFHppleElement.h to see which properties you might investigate, for example:
element.firstChild.content

Related

Setting UIView tags with int values but not get the same tag value back

I have a UIView that are menuiitems and these menu items are dynamically created where i stamp each uiview tag by increment of 1, but when i want to retrieve the uiview tag values when the user clicks on the menu item i get a different tag number.
I want to retrieve the tag which has the id stored so that i can post that id to a php script.
How do i retrieve the tags form when i set them?
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
UIView *tempView = recognizer.view;
NSNumber *tag = [NSNumber numberWithInt:tempView.tag];
int idCat = [tag intValue];
NSLog(#"TAG %d", idCat);
NSURLRequest *request =
[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:
#"http://localhost:8888/MAMP/WHFC/SubCategories.php?categoryid=%d", idCat]]];
int i = 0;
NSError *e;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&e];
NSArray *arrCategoryList =
[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&e];
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor whiteColor];
UIView *uiView = [[UIView alloc] init];
[uiView setFrame:CGRectMake(0, 480, 320, 480)];
[uiView setBackgroundColor:[UIColor grayColor]];
viewController.view = uiView;
UITableView *uiTableView = [[UITableView alloc] init];
[uiTableView setFrame:CGRectMake(0, 0, 320, 480)];
[uiView addSubview:uiTableView];
[self presentViewController:viewController animated:YES completion:nil];
}
This is the code that creates the menu items in another view:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString: #"http://localhost:8888/MAMP/WHFC/categories.php"]];
int i = 0;
NSError *e;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&e];
NSArray *arrCategoryList = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&e];
for(NSDictionary *dictCategory in arrCategoryList)
{
NSString *strCategoryId = [dictCategory objectForKey:#"CategoryId"];
NSString *strCategoryName = [dictCategory objectForKey:#"Name"];
NSLog(#"%# : %#",strCategoryId,strCategoryName);
UIView *linkMenu = [[UIView alloc] init];
[linkMenu setFrame:CGRectMake(10, i+1, 300, 35)];
linkMenu.tag = [NSString stringWithFormat:#"%d", strCategoryId];
linkMenu.layer.zPosition = 1;
[viewSlide3 addSubview:linkMenu];
[linkMenu setBackgroundColor:[UIColor blueColor]];
linkMenu.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.9];
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[linkMenu addGestureRecognizer:singleFingerTap];
UILabel *labelMenu = [[UILabel alloc] init];
[labelMenu setFrame:CGRectMake(20, 0, 300, 35)];
[labelMenu setFont:[UIFont systemFontOfSize:16]];
[labelMenu setTextColor:[UIColor whiteColor]];
[linkMenu addSubview:labelMenu];
[labelMenu setText:strCategoryName];
i = i + 35 + 1;
}
If you have a UIView lets say A inside which are placed all the other menu items which are also UIViews lets say B, C, and D then most probably the recognizer.view is returning you A no matter which of the B, C, or D are pressed.
Write this in your handleSingleTap function:
CGPoint touchPoint=[gesture locationInView:scrollView];
for(UIView * subView in myView ) //here myView should be the superView A where you have added all the menu item view B, C, and D
{
if(CGRectContainsPoint(subView.bounds, touchPoint))
{
NSNumber *tag = [NSNumber numberWithInt:subView.tag];
}
}
That tag variable will have your final tag that you need.

iOS scrollview adaption for landscape

I am using the following scrollview from a tutorial series. It works fine in portrait mode but the frame does not handle the switch to landscape mode. Is there a fast way to fix this? Thanks in advance.
- (void)viewDidLoad
{
[super viewDidLoad];
pageControlBeingUsed = NO;
NSString *plistFile = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#", self.displayRegion] ofType:#"plist"];
self.SituationData = [NSArray arrayWithContentsOfFile:plistFile];
self.singleSituation = [SituationData objectAtIndex:selectedIndexPath];
self.SituationScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)]; //distinguishing between iphone 4 and 5 screen
self.SituationScrollView.delegate = self;
self.SituationScrollView.showsHorizontalScrollIndicator = NO;
self.SituationScrollView.pagingEnabled = YES;
self.SituationScrollView.backgroundColor = [UIColor clearColor];
//adding to the view
[self.view addSubview:self.SituationScrollView];
//getting the base indicator
int baseNum = self.selectedIndexPath ;
self.plistFile = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#", self.displayRegion] ofType:#"plist"];
self.auswahl = [NSArray arrayWithContentsOfFile:self.plistFile];
self.SituationScrollView.contentSize = CGSizeMake(self.SituationScrollView.frame.size.width *[self.auswahl count], self.SituationScrollView.frame.size.height);
for (NSInteger i=1; i <= [[self auswahl] count]; i++){
UIImage *situationImage = [UIImage imageNamed:[NSString stringWithFormat:#"main%#", [[self.auswahl objectAtIndex:i - 1] objectForKey:#"nat_num"]]];
UIImageView *situationView = [[UIImageView alloc] initWithImage:situationImage];
UILabel *situationTitle = [[UILabel alloc] init];
situationTitle.text = [NSString stringWithFormat:#"%#", [[self.auswahl objectAtIndex: i - 1] objectForKey:#"species"]];
[situationTitle setTextColor:[UIColor blackColor]];
[situationTitle setBackgroundColor:[UIColor clearColor]];
UITextView *description = [[UITextView alloc] init];
description.text = [NSString stringWithFormat:#"%#", [[self.auswahl objectAtIndex: i - 1] objectForKey:#"description"]];
[description setTextColor:[UIColor blackColor]];
[description setBackgroundColor:[UIColor clearColor]];
[description setUserInteractionEnabled:NO];
situationView.frame = CGRectMake((320 * (i-1)) + SIT_IMG_X, 66, 94, 87);
situationTitle.frame = CGRectMake((320 * (i-1)) + TOP_DATA_X, 250, 240, 14);
description.frame = CGRectMake((320 * (i-1)) + DESC_X, DESC_Y, DETAIL_WIDTH, 100);
[self.SituationScrollView addSubview:situationView];
[self.SituationScrollView addSubview:situationTitle];
[self.SituationScrollView addSubview:description];
}
use a global BOOL variable
BOOl isLandscape =NO;
while writing frames
situationView.frame = CGRectMake(isLandscape?0:0, isLandscape?0:0, isLandscape?320:480 , isLandscape?480:320);
in orientation method write again
if(orientation == Landscape)
{
isLandscape=YES;
}
else
{
isLandscape=NO;
}
situationView.frame = CGRectMake(isLandscape?0:0, isLandscape?0:0, isLandscape?320:480 , isLandscape?480:320);
Check it as a sample it will work depending on it you can use
A little googlefu revealed this SO thread in which Mike states loading the UIScrollView in the viewWillAppear method instead of the viewDidLoad method, then the UIScrollView should appear as desired.

Add loading view controller before tableview shows

I have a tableView controller that loads my parsed XML data. It takes some time to do.
- (void)viewDidLoad
{
[super viewDidLoad];
CustomStringParser *customStringParser = [[CustomStringParser alloc] init];
// Set MORE logo in navigation bar
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Navigation"]];
// Download and parse XML data
RXMLElement *rxml = [RXMLElement elementFromXMLData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.morecobalt.co.uk/rss/?t=events"]]];
// Create an array to store each feed
eventsFeeds = [[NSMutableArray alloc] init];
// Loop through XML data
[rxml iterate:#"channel" usingBlock:^(RXMLElement *supportElement) {
[supportElement iterate:#"item" usingBlock:^(RXMLElement *repElement) {
// Assign element to string
NSString *title = [repElement child:#"title"].text;
NSString *subtitle = [repElement child:#"tagline"].text;
NSString *description = [repElement child:#"description"].text;
NSString *imageurl = [repElement child:#"image"].text;
NSString *startDate = [repElement child:#"start_date"].text;
NSString *endDate = [repElement child:#"end_date"].text;
// Assign element value to MoreCobalt.h propertys
currentFeed = [MoreCobaltEvents alloc];
currentFeed.title = title;
currentFeed.subtitle = subtitle;
currentFeed.imageurl = imageurl;
// DESCRIPTION FORMATTING
description = [customStringParser parseHTML:description];
description = [customStringParser parseLinesMultiple:description];
description = [customStringParser removeSocialSignifiers:description];
currentFeed.description = description;
// DATE FORMATTING
currentFeed.startDate = [customStringParser formatDate:startDate];
currentFeed.endDate = [customStringParser formatDate:endDate];
// Add a new object to the feeds array
[eventsFeeds addObject:currentFeed];
}];
}];
}
While the data is been parsed I want to add a loading screen with a activity indicator on. Im guessing this is going to be a sub view. How can I do this?
NOTE: Im using storyboards. Image below
Just drag an activity indicator component on your xib.
Declare a property in your .h file. Hook it up.
In your .m file in viewDidLoad call.
[self.activityIndicator starAnimating];
[self.activityIndicator.hidesWhenStopped = YES;
And then after your table loads call:
[self.activityIndicator stopAnimating];
No need for subviews.
Write below code in **AppDelegate.h**
UIActivityIndicatorView *progressIndicator;
UIView *progressIndicatorView;
Write below code in **AppDelegate.m**
-(void) addProgressIndicator:(UIView *)parentView
{
[self.progressIndicatorView removeFromSuperview];
self.progressIndicatorView = [[UIView alloc] initWithFrame:CGRectMake(0,0, parentView.frame.size.width,parentView.frame.size.height)];
self.progressIndicatorView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
self.progressIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake((parentView.frame.size.width - 70) / 2,(parentView.frame.size.height - 70) / 2,70,70)];
[self.progressIndicatorView addSubview:self.progressIndicator];
[parentView addSubview:self.progressIndicatorView];
[parentView bringSubviewToFront:self.progressIndicatorView];
[self.progressIndicatorView bringSubviewToFront:self.progressIndicator];
[self.progressIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.progressIndicator setHidesWhenStopped:YES];
[self.progressIndicator stopAnimating];
[self.progressIndicatorView setHidden:YES];
}
-(void) startProgressIndicator
{
[NSThread detachNewThreadSelector:#selector(showProgressIndicator) toTarget:self withObject:nil];
}
-(void) showProgressIndicator
{
[self.progressIndicatorView setHidden:NO];
[self.progressIndicator startAnimating];
}
-(void) stopProgressIndicator
{
[self.progressIndicator stopAnimating];
[self.progressIndicatorView setHidden:YES];
}
Call this methods where you want to show Progress Indicator,in viewDidLoad/ViewWillAppear .
Good Luck !!

-writeToURL is not overwriting the previous write

UPDATE #1: forgot to mention this is running on an iPad app
This is my revised code (still not working, but got rid of the unnecessary code):
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:#"custImage"] URLByAppendingPathExtension:#"png"];
NSError*writeError = nil;
[client.aClientImage writeToURL:fileURL options:0 error:&writeError];
NSAssert(writeError==nil, writeError);
// write appointment info
NSString *htmlString;
if(client.aClientEMail.length > 0) {
htmlString = [NSString stringWithFormat:NSLocalizedString(#"HTML_STRING1",nil),
client.aClientFirstName,
client.aClientLastName,
client.aClientEMail.length == 0? #"": client.aClientEMail,
client.aClientPrimaryPhone,
apptSelected.aServices,
fileURL];
}
else {
htmlString = [NSString stringWithFormat:NSLocalizedString(#"HTML_STRING2",nil),
client.aClientFirstName,
client.aClientLastName,
client.aClientPrimaryPhone,
apptSelected.aServices,
fileURL];
}
When I look at custImage in the XCode debugger, I see a different image from the previous image, which is correct. However, when it gets time to display the image at fileURL, it's a totally different image than custImage and is the same image that was displayed the first time!
UPDATE #2: I have figured out that fileURL has the correct image, but it is NOT being written to the device the second time (the first image is not being replaced).
UPDATE #3: this is the contents of htmlString that is displayed in the UIWebView popover:
<html><head><style type="text/css"> body {font-family: "Verdana"; font-size: 12;} </style></head><body>
<h2>Rolf Marsh</h2><p>phone: 213-555-1234<p>services: Art, Decals<p><img src="file:///private/var/mobile/Applications/FEE7159E-1FF8-4B94-A446-2A4C72E0AD41/tmp/custImage.png"/></body></html>
Any suggestions on how to fix this?
you never write the data to disk as far as I can see.
Only in the commented out section you attempt to.
Write it in between:
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:#"custImage"] URLByAppendingPathExtension:#"png"];
//write
NSError*writeError = nil;
[client.aClientImage writeToURL:fileURL options:0 error:&writeError];
NSAssert(writeError==nil, writeError);
//read / use in the html or so
...
Dont forget to reload the web view or whatever you use to show the html
I figured it out... for others that are having the same problem, here is the code that works. Notice that I do NOT save it to a temporary file, since I already have the image in the Core Data entity. Here's the code:
-(void) showExistingAppointmentDetails: (AppointmentInfo *) apptSelected {
// make rectangle to attach popover
CGRect rectangle = CGRectMake( [apptSelected.aPosX floatValue], [apptSelected.aPosY floatValue],
[apptSelected.aPosW floatValue], [apptSelected.aPosH floatValue]);
// see if this is for staff; if so, don't display anything
if([apptSelected.aApptKey isEqual: #"Staff"])
return;
NSPredicate *predicate = ([NSPredicate predicateWithFormat: #"aClientKey == %#", apptSelected.aApptKey ]); // was aApptKey
ClientInfo *client = [ClientInfo MR_findFirstWithPredicate:predicate inContext:localContext];
UIImage *image = [UIImage imageWithData:client.aClientImage]; // image is good <---------
// write appointment info into html string
NSString *htmlString;
if(client.aClientEMail.length > 0) {
htmlString = [NSString stringWithFormat:NSLocalizedString(#"HTML_STRING1",nil),
client.aClientFirstName,
client.aClientLastName,
client.aClientEMail.length == 0? #"": client.aClientEMail,
client.aClientPrimaryPhone,
apptSelected.aServices,
[self htmlForPNGImage:image]];
}
else {
htmlString = [NSString stringWithFormat:NSLocalizedString(#"HTML_STRING2",nil),
client.aClientFirstName,
client.aClientLastName,
client.aClientPrimaryPhone,
apptSelected.aServices,
[self htmlForPNGImage:image]];
}
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 250, 300)];
popoverView.backgroundColor = [UIColor colorWithWhite:(CGFloat)1.0 alpha:(CGFloat)1.0]; // frame color?
popoverContent.view = popoverView;
//resize the popover view shown in the current view to the view's size
popoverContent.contentSizeForViewInPopover = CGSizeMake(250, 300);
// add the UIWebView for RichText
UIWebView *webView = [[UIWebView alloc] initWithFrame:popoverView.frame];
webView.backgroundColor = [UIColor whiteColor]; // change background color here
// add the webView to the popover
[webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:nil]];
[popoverView addSubview:webView];
// if previous popoverController is still visible... dismiss it
if ([popoverController isPopoverVisible]) {
[popoverController dismissPopoverAnimated:YES];
}
//create a popover controller
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[popoverController presentPopoverFromRect:rectangle inView:self
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
- (NSString *) htmlForPNGImage:(UIImage *) image {
NSData *imageData = UIImagePNGRepresentation(image);
NSString *imageSource = [NSString stringWithFormat:#"data:image/png;base64,%#",[imageData base64Encoding]];
return [NSString stringWithFormat:#"%#", imageSource];
}

saving with NSMutableData and NSKeyedArchiver a UIObject

I am building an app using storyboard. I have a view controller where the user has a set of tools (UILabels, images...), and can add these items by clicking on a specific button. When I exit the view controller or closes the app though all the data is lost. so I tried setting up a save button in this way:
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *cameraButton = [[UIBarButtonItem alloc]
initWithTitle:#"Camera"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(useCamera:)];
UIBarButtonItem *cameraRollButton = [[UIBarButtonItem alloc]
initWithTitle:#"Camera Roll"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(useCameraRoll:)];
NSArray *items = [NSArray arrayWithObjects: cameraButton,
cameraRollButton, nil];
[toolbar setItems:items animated:NO];
mouseMoved = 0;
array = [[NSMutableArray alloc]init];
array2 = [[NSMutableArray alloc]init];
array3 = [[NSMutableArray alloc]init];
NSFileManager *filemgr; NSString *docsDir; NSArray *dirPaths;
filemgr = [NSFileManager defaultManager];
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the data file
dataFilePath = [[NSString alloc] initWithString: [docsDir
stringByAppendingPathComponent: #"data.archive"]];
// Check if the file already exists
if ([filemgr fileExistsAtPath: dataFilePath]) {
dataArray = [NSKeyedUnarchiver unarchiveObjectWithFile: dataFilePath];
array = [dataArray objectAtIndex:0]; array2 = [dataArray objectAtIndex:1]; array3 = [dataArray objectAtIndex:2];
}}
-(void)saveData{
NSMutableArray *contactArray;
contactArray = [[NSMutableArray alloc] init]; [contactArray addObjectsFromArray:array]; [contactArray addObjectsFromArray:array2]; [contactArray addObjectsFromArray:array3]; [NSKeyedArchiver archiveRootObject:
contactArray toFile:dataFilePath];
[self.view addSubview: image1];
[self.view addSubview: text1];
[self.view addSubview: label1];
}
when I press the buttons the you can see that the codes are triggers (NSLog), but nothing happens. in the above example when I click save, the UILabel the user has created (alloc), should be saved, and when the app is open again, the button unarchive should place the label exactly how it is, and in the same position. I have to do tho even for the UIImageViews, and UITextFields.
Since I added all the user created labels... in an array, I want to save the whole objects in the array. The above code does not work though. I can't understand why.this is how I created the array and the object (in .h I added NSMutableArray *array;)
CGRect labelFrame = CGRectMake( 400, 100, 100, 30);
label1 = [[UILabel alloc] initWithFrame: labelFrame];
[label1 setText: #"Untitled"];
[label1 setTextColor: [UIColor orangeColor]];
[self.view addSubview:label1];
label1.backgroundColor = [UIColor clearColor];
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scalePiece:)];
[label1 addGestureRecognizer:pinchGesture];
if (array == nil) array = [[NSMutableArray alloc]init];
[array addObject:label1];
thanks in advance for the help!!
Try logging your loaded objects and you should see that they are actually loaded. You don't see them of course since you don't add them to the view hierarchy. Try adding those lines after you get your objects from the dictionary:
[self.view addSubview: label1];
[self.view addSubview: text1];
[self.view addSubview: image1];
This might work, but it is not a good idea though. You really should read some introductory material to object-oriented programming and the Model/View/Controller (MVC) design pattern.

Resources