When and where are controller's properties supposed to be set? - iphone

This time, I was wondering when I was supposed to set my properties ...
I got a nav bar which I use to push a new controller (controlling a Web View) :
NewsViewController *webViewController = [[NewsViewController alloc] init]; // I create my controller
webViewController.urlText = #"http://www.google.fr"; // I set the property
InfonulAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.newsNavController pushViewController:webViewController animated:YES];
[webViewController release];
I don't know why but the code below doesn't work :
- (void)viewDidLoad { //viewDidLoad from my webViewController
[super viewDidLoad];
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlText];
//URL Requst Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webView loadRequest:requestObj];
}
I just want to create a UIWebView but I need to give the controller the URL to use !
Any idea where and when my urlText property needs to be set ?!?
Cheers,
Gauthier

Do you use property correctly? Like
#property(nonatomic,retain) NSString *urlText;
If so, try to use a customized init method like this;
-(id)initWithUrl:(NSString *)url
{
if(self = [super init])
{
self.urlText = url;
}
return self;
}
dont forget to release urlText in dealloc. Now use;
NewsViewController *webViewController = [[NewsViewController alloc] initWithUrl:#"someUrl"];

Related

shouldStartLoadWithRequest delegate method never called

I'm creating an app which has a webview. When user click to a link or a button in the webview, I want to be able to get the new url, and edit the new url.
shouldStartLoadWithRequest should do the trick, but that method is never called when I click to a link. I cannot find why this doesn't work.
I have read somewhere that I need to add this line :
webView.delegate = (id)self;
I tried it, and still get the same issue. Please help
AppDelegate.m
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *currentURL = [[request URL] absoluteString] ;
NSLog(#"Url: %#", currentURL);
return YES;
}
Controller.m
- (void)viewDidLoad
{
webView.delegate = (id)self;
NSString *tokenString = #"123";
[super viewDidLoad];
NSString *fullURL = [[NSString alloc] initWithFormat:#"http://192.168.1.69:8888/webapp/test.php?uid=%#", tokenString];
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
}
If your Controller instance adds itself as the delegate then the method you add to the AppDelegate instance will never be called.
Move the shouldStartLoadWithRequest method into your Controller class.
You've set your view controller as the web view's delegate. But then you've implemented the UIWebView delegate method in our application's delegate instead.
Try implementing that delegate method in your view controller. Your view controller is your web view's delegate.

UI Activity View Controller Showing in different language?-iOS

I am creating an app where the user can share different forms. What is weird is when I test the app on a iPhone, the Activity View controller works fine
But when I do the exact same thing on the ipad, but in a different storyboard. It does this:
Here is the code from which both of these views are getting their actions:
#import "FluteS.h"
#import "TUSafariActivity.h"
#import "ARChromeActivity.h"
#interface FluteS ()
#end
#implementation FluteS
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(IBAction)actionButton:(id)sender;{
NSLog(#"actionButton pressed");
NSBundle *bundle=[NSBundle mainBundle];
NSString *filePath = [bundle pathForResource:#"Flute" ofType: #"pdf"];
NSURL *fileURL= [NSURL URLWithString:#"http://www.friendswoodmustangband.org/wp-content/uploads/2012/04/Flute-Audition-Scales1.pdf"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSArray *activityItems = #[fileUrl, fileURL];
ARChromeActivity *chromeActivity = [[ARChromeActivity alloc] init];
TUSafariActivity *TUSafari = [[TUSafariActivity alloc] init];
NSArray *applicationActivities = [NSArray arrayWithObjects:TUSafari,chromeActivity, nil];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities: applicationActivities];
activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities];
activityVC.excludedActivityTypes = #[UIActivityTypeAssignToContact, UIActivityTypePostToWeibo];
[self presentViewController:activityVC animated:YES completion:nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSBundle *bundle=[NSBundle mainBundle];
NSString *filePath = [bundle pathForResource:#"Flute" ofType: #"pdf"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:fileUrl];
[_webView loadRequest:request];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I have already checked the localized part of the Info.plist, but I can't Figure out why it works on the iPhone, but not on the iPad. Does anybody have any idea what is happening?
When presenting the view controller, you must do so using the appropriate means for the current device. On iPad, you must present the view controller in a popover. On iPhone and iPod touch, you must present it modally.
You can use the following code for iPad.
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[#"something"] applicationActivities:nil];
self.popover = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
self.popover.delegate = self;
[self.popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
Hope it helps you.

Releasing view from stack, tab bar with nav controller

So I am working on a vital update to an app I have on the appstore. I have an app with a tab bar and a nav controller. When the user selects an item from the list it sends the link it is getting from the xml file sent from my server to a detail view controller that is only a web view. The problem I'm having is when the user goes back to the tableview which is the root view for that tab the detail view isn't being released. When you select the other options in the app, the detail view doesn't change. It's not that my data isn't being released from the uishared application data but its the view isn't releasing. I know that there are many similar items like this on here and i've tried all of them. I will give you some of my code and greatly appreciate other tips and tricks. Im 15 and just getting into development so any info helps. Heres the code i think is necessary for anyone to help.
TableViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * storyLink = [[stories objectAtIndex: storyIndex] objectForKey: #"link"];
// clean up the link - get rid of spaces, returns, and tabs...
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#"\n" withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
videoDetailViewController.title = #"Videos";
ExampleAppDataObject* theDataObject = [self theAppDataObject];
theDataObject.videoData = storyLink;
if (self.videoDetailViewController == nil)
{
VideoDetailViewController *aBookDetail = [[[VideoDetailViewController alloc] initWithNibName:#"VideosDetailView" bundle:[NSBundle mainBundle]] autorelease];
self.videoDetailViewController = aBookDetail;
[aBookDetail release];
aBookDetail = nil;
}
[self.navigationController pushViewController:videoDetailViewController animated:YES];
}
DetailViewController:
#import "VideoDetailViewController.h"
#import "RSSEntry.h"
#import "ExampleAppDataObject.h"
#import "AppDelegateProtocol.h"
#implementation VideoDetailViewController
#synthesize activityIndicator;
#synthesize webView;
#synthesize pasteboard;
- (ExampleAppDataObject*) theAppDataObject;
{
id<AppDelegateProtocol> theDelegate = (id<AppDelegateProtocol>) [UIApplication sharedApplication].delegate;
ExampleAppDataObject* theDataObject;
theDataObject = (ExampleAppDataObject*) theDelegate.theAppDataObject;
return theDataObject;
}
- (void)viewDidLoad
{
ExampleAppDataObject* theDataObject = [self theAppDataObject];
NSString *urladdress = theDataObject.videoData;
NSURL *url = [NSURL URLWithString:urladdress];
NSURLRequest *requestobj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestobj];
pasteboard = [UIPasteboard generalPasteboard];
[super viewDidLoad];
}
- (void)dealloc
{
[webView release];
webView = nil;
[activityIndicator release];
[pasteboard release];
[VideoDetailViewController release];
[urlData release];
urlData = nil;
[super dealloc];
}
#end
I skipped a lot of the code that i didnt feel was necessary. If you want the actual files then email me at evan.stoddard#me.com
Don't release the webview in the detailViewController page, instead, put
[webView loadRequest:requestobj]; in in viewDidAppear(), not viewDidLoad
Also:
One way to make the transition smoother, change:
if (self.videoDetailViewController == nil) {
VideoDetailViewController *aBookDetail = [[[VideoDetailViewController alloc] initWithNibName:#"VideosDetailView" bundle:[NSBundle mainBundle]] autorelease];
self.videoDetailViewController = aBookDetail;
[aBookDetail release];
aBookDetail = nil;
}
[self.navigationController pushViewController:videoDetailViewController animated:YES];
Should be:
VideoDetailViewController *aBookDetail = [[VideoDetailViewController alloc] initWithNibName:#"VideosDetailView" bundle:[NSBundle mainBundle]] ;
[self.navigationController pushViewController:videoDetailViewController animated:YES];
[aBookDetail release];
Thanks to Anna Billstrom, I realized that I also should be using viewDidAppear instead of viewDidLoad. This is because I am passing data to the controller through an external data class when an item is selected from the table view. Therefore, the detail view controller is loading before there is data to load from the external data class. viewDidAppear solves this problem by getting data once the view loads after the cell is selected and there is data in the external class.

iOS - Why my NSURL isn't retained in the init method?

I'm creating a new UIViewController with 2 properties :
#property (retain, nonatomic) NSURL *url;
#property (retain, nonatomic) NSString *title;
and synthetised :
#synthesize url = _url;
#synthesize title = _title;
in my custom init method i'm not using the setter like the Memory Management Guide says but when I need to use the properties in the viewDidLoad, the url seems empty, the title doesn't
- (id)initWithURL:(NSURL *)url andTitle:(NSString *)titleTemp
{
self = [super initWithNibName:#"navigatorViewController" bundle:nil];
if (self) {
_url = url;
_title = titleTemp;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[_titreBarButtonItem setTitle:_title];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:_url];
[_webView loadRequest:urlRequest];
[urlRequest release];
}
I can see my title but my web view is blank.
If I use self.url in the init, it's working !
Do you have an idea ?
PS : Here's how I call my init :
NSString *urlString = [[[NSBundle mainBundle] pathForResource:#"infos" ofType:#"html"] copy];
NSURL *url = [[NSURL alloc] initFileURLWithPath:urlString];
[urlString release];
navigatorViewController *navigatorVC = [[navigatorViewController alloc] initWithURL:url andTitle:#"Infos"];
[url release];
[self presentViewController:navigatorVC animated:YES completion:nil];
[navigatorVC release];
Thanks a lot
you are setting up the properties as retain, but this only applies if you use the synthesized getters. By setting the value directly on the ivar, you are bypassing this and the value is not being retained
you should be doing (probably not a great way when you already have setters):
_url = [url retain];
or better:
self.url = url;
or even better as matt said in the comments: use ARC
You must retain the URL either using :
self.url = url;
in the init method or call the retain after assigning the url in the init method like this.
_url = url;
[_url retain];
You need to add a reference (for what you hold) using copy or retain:
_url = [url copy];
_title = [titleTemp copy];
or
_url = [url retain];
_title = [titleTemp retain];
Well if you write a custom init method you need to do the retain your self:
- (id)initWithURL:(NSURL *)url andTitle:(NSString *)titleTemp
{
self = [super initWithNibName:#"navigatorViewController" bundle:nil];
if (self) {
_url = [url retain];
_title = [titleTemp retain];
}
return self;
}
That it worked with title is just that the variable is probably released later then the NSURL passes in the init method.

UIWebView not loading URL when URL is passed from UITableView

So i'm building a webView into my application to show the contents of a URL that I am passing from a selection in a UITableView. I know the UIWebView is loading content properly because if you hard code say http://www.google.ca into the NSURL then it loads fine, however when I'm passing the URL that I parsed from an RSS feed back from the UITableView it won't load the URL properly. I tried the debugger and the URL is coming out as nil right before I try and parse it, however I can use NSLog to print the value of it out to the console.
here's the code in my UIViewController that has my UIWebView
#import <UIKit/UIKit.h>
#interface ReadFeedWebViewController : UIViewController
{
NSString *urlToGet;
IBOutlet UIWebView *webView;
}
#property(nonatomic, retain) IBOutlet UIWebView *webView;
#property(nonatomic, retain) NSString *urlToGet;
#end
Here's the code for my implementation's viewDidLoad method...
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Url inside Web View Controller - %#", urlToGet);
NSURL *url = [NSURL URLWithString:urlToGet];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
}
Once again, I can print the URL to NSLog fine and if I hard code the URL into the NSURL object then it will load fine in the UIWebView. Here is where I'm setting the value in my UITableViewController...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReadFeedWebViewController *extendedView = [[ReadFeedWebViewController alloc] init];
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
extendedView.urlToGet = [[stories objectAtIndex: storyIndex] objectForKey:#"link"];
//NSLog([[stories objectAtIndex: storyIndex] objectForKey:#"summary"]);
NSLog([[stories objectAtIndex: storyIndex] objectForKey:#"link"]);
[self.navigationController pushViewController:extendedView animated:YES];
[extendedView release];
}
However, since I can print the value using NSLog in the extendedView view controller I know it's being passed properly. Cheers
The urlToGet is null into your ReadFeedWebViewController in the viewDidLoad method because when this method is call this variable is not yet affected. The viewDidLoad is call when the initialisation of the ViewController is finished.
I should you to call it in the viewWillAppear method like that:
- (void)viewWillAppear:(BOOL)animated {
NSURL *url = [NSURL URLWithString:urlToGet];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
}
Also, there is a memory leak in your code. You should release extendedView after pushing it on the navigation controller.
ReadFeedWebViewController *extendedView = [ReadFeedWebViewController new];
if (extendedView != nil) {
... setup extendedView here ...
[self.navigationController pushViewController:extendedView animated:YES];
[extendedView release];
}
Try this
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0];