When selecting a row in table, it switches to blank screen - html

in part of my app (storyboard) I have a table view with various rows, and when I select a row, an html file should be displayed. Instead when I select a row, I get a blank screen instead.
I thought I needed another view controller after the tableview controller, but I get the same issue whether I have one or not.
In my table controller .m file I have the following code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
articleIndex = indexPath.row;
WebView *selectedArticle = [[WebView alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:selectedArticle animated:YES];
[selectedArticle release];
That is allowing me to select a row and the screen changes to a blank one, rather than loading the relevant html file.
I have in my resources folder a .h and .m file as follows:
webView.h
#import <UIKit/UIKit.h>
#import "globals.h"
#interface WebView : UIViewController{
NSArray *articleNames;
IBOutlet UIWebView *webView;
}
#property(nonatomic, retain)IBOutlet UIWebView *webView;
#end
webView.m
#import "WebView.h"
#implementation WebView
#synthesize webView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
articleNames = [[NSArray arrayWithObjects:
#"chapter1",
#"chapter2",
#"chapter3",
#"chapter4",
#"chapter5",
#"chapter6",
nil] retain];
NSString *chapterName = [[NSString alloc] initWithString:[articleNames objectAtIndex:articleIndex]];
NSString *path = [[NSBundle mainBundle] pathForResource:chapterName ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:path];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
[webView loadRequest:urlRequest];
[chapterName release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
I can't see what I have done wrong here, any advice? I'm not sure how to get the html files to display or where I need to make changes to allow it. If I remove the HTML files from the project the app crashes so it's definitely loading them but for some reason not displaying...

Well first off where is "articleIndex" I see you set it in your tableViewController but it is not webView.h or webView.m. I would suggest first adding in a NSLog
NSURL *url = [NSURL fileURLWithPath:path];
NSLog(#"Article URL:%#", url);
This will let you see if the url is correct first. Second it looks like you connected your UIWebView with interface builder, so make sure that the webView is connect correctly. You can also test the webView buy using:
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: #"http://www.apple.com"]];
And see if apple.com loads. If it does then you know your issue is with your html files or the paths to them.

Related

How to parse html tag url and make it clickable in a label

I need to parse a html tag. For exemple:
<a href=“http://www.google.it”>MY LINK</a>
So, how can I detect this link, and make it clickable in a label? Only the link clickable.
Thanks
You can just use TextView. With textView you will set that the attributedText has an attribute that is the link you want
NSString *url = #"https://www.stackoverflow.com";
NSString *stringLink = #"My link";
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:stringLink attributes:nil];
[attrString addAttribute:NSLinkAttributeName value:url range:NSMakeRange(0, [attrString.string length])];
self.textView.attributedText = attrString;
Edit:
Make sure to format correctly your String to be sure to catch your url after "href=\"" and the stringLink after ">" character.
Try this way In ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextView *textView;
#end
And ViewController.m
#import "ViewController.h"
#interface ViewController ()<UITextViewDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITapGestureRecognizer *tapGesture =[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOnTextView)];
[self.textView addGestureRecognizer:tapGesture];
[tapGesture setNumberOfTapsRequired:1];
[self.view addSubview:self.textView];
self.textView.delegate=self;
NSString * testStr=#"The world’s most popular camera is more advanced than ever. The 12-megapixel iSight camera captures sharp, detailed photos. It takes brilliant 4K video, up to four times the resolution of 1080p HD video. https://www.google.com/gmail/about/# iPhone 6s also takes selfies worthy of a self-portrait with the new 5-megapixel FaceTime HD camera. And it introduces Live Photos, a new way to relive your favourite memories. It captures the moments just before and after your picture and sets it in motion with just the press of a finger.";
self.textView.text = testStr;
self.textView.dataDetectorTypes = UIDataDetectorTypeLink;
}
- (void)openScheme:(NSString *)scheme {
UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString:scheme];
if ([application respondsToSelector:#selector(openURL:options:completionHandler:)]) {
[application openURL:URL options:#{}
completionHandler:^(BOOL success) {
NSLog(#"Open %#: %d",scheme,success);
}];
} else {
BOOL success = [application openURL:URL];
NSLog(#"Open %#: %d",scheme,success);
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)tapOnTextView
{
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:self.textView.text];
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
[detector enumerateMatchesInString:self.textView.text options:kNilOptions range:NSMakeRange(0, [self.textView.text length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSLog(#"Values: %#", result);
if (result.resultType == NSTextCheckingTypeLink)
{
NSLog(#"matched: %#",result.URL);
[self openScheme:[result.URL absoluteString]];
}
}];
self.textView.attributedText=attributedString;
}

How can I load an image from a Drupal field to UIImageView?

I'm building an app for my Drupal based website. I currently have my iOS application pulling data from the MySQL database (e.g. Article titles and descriptions). Does anyone know what sort of code I would use to display an article's corresponding image (uploaded via a Drupal field) in an UIImageView?
Here's a quick snippet of the code I'm using to pull text from my Drupal site.
DoctorsViewController.h
#interface DoctorsViewController : UIViewController {
IBOutlet UITableView *DoctorsTableView;
NSArray *Doctors;
NSMutableData *data;
}
DoctorsViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"MY URL HERE"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
Doctors = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
[DoctorsTableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"The download could not complete - please make sure that you're connected to 3G or Wi-Fi." delegate:nil
cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (int)numberOfSectionsInTableView: (UITableView *)tableview
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [Doctors count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DoctorsTableIdentifier = #"DoctorsCell";
DoctorsCell *cell = (DoctorsCell *)[tableView dequeueReusableCellWithIdentifier:DoctorsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"DoctorsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.firstnameLabel.text = [[Doctors objectAtIndex:indexPath.row] objectForKey:#"node_title"];
cell.descriptionLabel.text = [[Doctors objectAtIndex:indexPath.row] objectForKey:#"Opening Paragraph"];
return cell;
}
That isn't as straightforward as it sounds - Drupal stores its field data in a very specific way, and URIs to the images are addressed with a schema rather than having a relative or absolute path (e.g. public://path/to/image.jpg as opposed to /sites/default/files/path/to/image.jpg)
You can get the image URIs for a node straight from the DB like this (assuming your article type uses the standard field_image field):
SELECT fm.uri
FROM {file_managed} fm
INNER JOIN field_data_field_image fi ON fi.entity_type = 'node' AND fi.bundle = 'article' AND fi.deleted = 0 AND fi.field_image_fid = fm.fid
WHERE fi.entity_id = <nid>
Where <nid> is the node ID. From there you'll need to perform whatever logic you need to translate the paths to something useful for your iOS app. Drupal uses file_create_url() to perform the same task, so that's your best starting point for inspiration. Depending on your setup you may well get away with just doing a string replace on public:// to http://example.com/sites/default/files/.
Long term, you might want to look at adding the Services module and consuming the REST API in your app, instead of querying the DB directly. It'll take a lot of the strain of preparing Drupal's data out of your hands so you can just deal with what you need.

Unable load a url from a database

This code allows me to pull image names from my mysql lite database without any issues.
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage * image = [UIImage imageNamed: self.munsterData.image];
self.imageView.image = image;
}
I would also like to pull specific urls from my database and load them into a UIWebView using this code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL * myUrl = [[NSURL alloc] initWithString: self.munsterData.twitter];
NSURLRequest * myNSURLRequest = [[NSURLRequest alloc]initWithURL:myUrl];
[twitterView loadRequest:myNSURLRequest];
}
What am I doing wrong? My app instantly crashes when I select the url link. If I replace:
NSURL * myUrl = [[NSURL alloc] initWithString: self.munsterData.twitter];
with
NSURL * myUrl = [[NSURL alloc] initWithString: #"http://www.google.com"];
The google website loads successfully. But for some reason I cannot get url's from my database to load.
munsterData:
#property (nonatomic, retain) NSMutableArray * munsterData;
twitter:
const char * twitterStr = sqlite3_column_text(statement, 7);
NSString * twitter = [NSString stringWithUTF8String:twitterStr];
p.twitter = twitter;
Put this right after the [super viewDidLoad]; and provide feedback.
NSLog(#"%#", self.munsterData.twitter);
if ([self.munsterData.twitter isKindOfClass:[NSString class]]) {
NSLog(#"is string");
}
You Code is perfect for loading any url in UIWebview. good way to start. But make sure the below points before loading url in UIWebview with the example of your code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL * myUrl = [[NSURL alloc] initWithString: self.munsterData.twitter];
NSURLRequest * myNSURLRequest = [[NSURLRequest alloc]initWithURL:myUrl];
[twitterView loadRequest:myNSURLRequest];
}
Debug your code and check if "self.munsterData.twitter" is getting url or not. Good way to program is to check if your string has value or not only than after than perform another operation on string.
Check if you string Contains "http://" or "https://" in your "self.munsterData.twitter". if not available than please add using string with format method of NSString Class.
For Better Programming, Please use the method for converting in to real url with the below method:
- NSString *url_String = [self.munsterData.twitter strgingByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

Unable to "pass data" from a UITableViewController to a UIViewController

I am in troubles :)
I am unable to acheive my project because i cannot pass the data from my UITableView to a DetailView (UIViewController)
I am a beginner so i certainly do something wrong but i don't know what. I have red several tutorials and it seems to be ok ... but it's not !
Here is the .h of my UITableViewController :
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "XMLParser.h"
#import "ColzaDetailViewController.h"
#interface ColzaViewController : UITableViewController <XMLParserDelegate>
{
XMLParser *parser;
NSDictionary *colzaInfos;
}
#property (nonatomic, retain) NSDictionary *colzaInfos;
#end
I have create an NSDictionary to store the data I need to pass to the detailView (ColzaDetailViewController)
Here is the part of my UITalbeViewController .h wich is interresting for my problem :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ColzaDetailViewController *detailViewController = [[ColzaDetailViewController alloc] initWithNibName:#"ColzaDetail" bundle:[NSBundle mainBundle]];
colzaInfos = [parser.stories objectAtIndex:indexPath.row];
detailViewController._colzaInfos = colzaInfos;
[self.navigationController pushViewController:detailViewController animated:YES];
NSLog(#"TEST MainView : %#", detailViewController._colzaInfos);
detailViewController = nil;
}
I think everything is ok here. I have put a NSLog (TEST MainView) to check if there is something in my NSDictionary _colzaInfos.
So here are my .h and .m of my DetailVieuw (UIVIewController)
.h
#import <UIKit/UIKit.h>
#import "ColzaViewController.h"
#interface ColzaDetailViewController : UIViewController
{
IBOutlet UILabel *colzaSettle;
NSDictionary *_colzaInfos;
}
#property (nonatomic, strong) NSDictionary *_colzaInfos;
#property (nonatomic, retain) IBOutlet UILabel *colzaSettle;
#end
.m
#import "ColzaDetailViewController.h"
#implementation ColzaDetailViewController
#synthesize _colzaInfos, colzaSettle;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
// Implement loadView to create a view hierarchy programmatically, without using a nib.
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
colzaSettle = [_colzaInfos objectForKey:kCloture];
NSLog(#"TEST DetailView : %#", _colzaInfos);
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
As you can see in the viewDidLoad, i have put a second NSLog (TEST DetailView) in order to check one more time if there is something in my Dictionary
And here are the log :
2012-03-14 16:23:54.240 Mobile Settles[7173:f803] TEST DetailView : (null)
2012-03-14 16:23:54.241 Mobile Settles[7173:f803] TEST MainView : {
date = "13/03/2012\n ";
echeance = "Ao\U00fbt 2012\n ";
settle = "453.25\n ";
variation = "5.75";
}
So As you can see the log for DetailView is NULL but in the MainView contains data.
But i need to get those data in the DetailView in order to display them.
The only thing it seem "strange" for me at this step is the _colzaInfos Dictionary is not alloc and init at anytime ... But i have try to allocate it and initialize it in the .m of the detailViewController but my log was at this time
TEST DetailView : {}
Someone can help me to understand what i am doing wrong.
(if you need another part of my code to check something ... feel free to ask.)
Thanks a lot for help
As you told me to do, i have put the line of code at this place, please let me know if i am wrong. And as i told in the comment, When i put a breakpoint directly in this part of code and when i Run the program, the breakpoint stop the process AFTER the NSLog. And if i try to alloc/init it before, i have nothing : TEST detailView : { }.
Sorry but it does not work :(
The code :
#implementation ColzaDetailViewController
#synthesize _colzaInfos, colzaSettle;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
if (! _colzaInfos)
_colzaInfos = [[NSDictionary alloc] init];
}
return self;
}
Add this to your initWithNibName method in ColzaDetailViewController.m.
if (! _colzaInfos) _colzaInfos = [[NSDictionary alloc] init];
It is same issue if you're using an NSArray. You have to initialize the variable at some point for it to be able to hold data. You've only declared it in the .h file.

Three20 display local html file

I'm trying to display a local html file from a three20 table controller. The table shows up correctly, but when I select the item, all I get is a blank screen. If I use an external URL, the page shows correctly. I haven't tried using UIWebView, but I was wondering if there was an easy way using the Three20 framework.
Thanks.
EDIT: I forgot that has changed recently...
Assuming you have registered a TTWebController in your navigator that way :
TTNavigator* navigator = [TTNavigator navigator];
TTURLMap* map = navigator.URLMap;
[map from:#"*" toViewController:[TTWebController class]];
You can simply open a local html file that way :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
TTOpenURL([url description]);
Then all you have to to is to add TTTableLinkedItem or subclass (almost all of TT*Cell are) to your dataSource with a local file URL like that :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
TTTableTextItem *item = [TTTableTextItem itemWithText:#"foobar" URL:[url description]];
Much simpler that what I wrote before...
ENDOFEDIT
Forget whats under, unless you're interested in others solutions... (more complex... or not, see last one)
Basically here is how you load content in a UIWebView :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[webView loadRequest:urlRequest];
The three20 TTWebController can take a request in a query :
- (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query {
if (self = [self initWithNibName:nil bundle:nil]) {
NSURLRequest* request = [query objectForKey:#"request"];
if (nil != request) {
[self openRequest:request];
} else {
[self openURL:URL];
}
}
return self;
}
So to open a local html file in a TTWebController you could do this :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[[TTNavigator navigator] openURLAction:
[[[TTURLAction actionWithURLPath:#"url://to/your/ttwebcontroller"]
applyQuery:[NSDictionary dictionaryWithObject:ulrRequest
forKey:#"request"]]
applyAnimated:YES]];
Now the last part, to trigger this from a TTTableViewController...
You have in your ViewController to implement :
- (void)didSelectObject:(id)object atIndexPath:(NSIndexPath*)indexPath {
// there you retrieve a *TTTableItem* corresponding to your row
// and call previous snippet from URL...
// TTTableItem class has userInfo property you could use:
TTTableItem *item = (TTTableItem *)object;
NSString *htmlFile = item.userInfo.
[self openLocalHtmlFile:htmlFile];
}
Hope that helps!
Nothing tested, at all, should not compile or whatsoever, but that is a solution.
That's a solution using basic three20 + iOS features. You could also write a TTCustomWebController inheriting from TTWebController that would take urls like #"myapp://openLocalHtml?file=credits" that's not that hard to do...
...That here is a draft :
#interface TTCustomWebController : TTWebController {}
#end
#implementation TTCustomWebController
- (id)initWithFile:(NSString *)name {
self = [super init];
if (self) {
NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:#"html"];
NSURL *URL = [NSURL fileURLWithPath:filePath];
[self openURL:URL];
}
return self;
}
#end
Then you could simply use TTTableLinkedItem in your datasource pointing to these #"myapp://openLocalHtml?file=credits"...
Good luck! :)