Generate a website screen capture in ios - objective-c

As the question says, on a iOS device if a user inputs a URL in uitextfield I want to generate a thumbnail capture of this URL. How can this be achieved? Unfortunately I don't have a clue where to start from.
Of course one way I can do this is to send this URL to backend & get the image screenshot from there. I know how one can do this kinda stuff using python or php. But I want to avoid the extra round trip to my backend servers.
I want something like - (uiimage *)screenCapture:(nsurl *)url

As per your question i think you'll want to manipulate the generated screenshot afterwards. You'll add a UIWebView programmatically to load the needed URL then take a snapshot of the loaded web page then remove the UIWebView
Here are the steps
a UIImageView to your viewController and connect it to your viewController class
#property (weak, nonatomic) IBOutlet UIImageView *image_Thumbnail;
having the URL in a variable named "webPageUrlString" add the following lines
UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.frame];
webView.backgroundColor = [UIColor redColor];
NSURL *websiteUrl = [NSURL URLWithString:**webPageUrlString**];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:websiteUrl];
[webView loadRequest: urlRequest];
webView.delegate = self;
[self.view addSubview:webView];
right now you have requested to load the URL but can't render the snapshot unless the web page is fully loaded,so you'll need to wait for the web page loading notification.In order to that you must subscribe to the webView delegate in the header file like that
#interface ViewController : UIViewController<UIWebViewDelegate>
Now you'll implement the "webViewDidFinishLoad" and take the snapshot you want then hide and remove the webView.
-(void)webViewDidFinishLoad:(UIWebView *)webView{
viewImage = [[UIImageView alloc] initWithFrame:self.view.frame];
viewImage.backgroundColor = [UIColor greenColor];
UIGraphicsBeginImageContext(webView.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
viewImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[webView setAlpha:0];
[webView removeFromSuperview];
[self.view addSubview:viewImage];
}
Now you have the screenshot you want in the property called "viewImage" and you can do what ever you want with it ;)

Related

play multiple videos smoothly in CollectionView like Facebook

I'm trying to implement an AVPlayer into each row of a Collection cell but I don't find any good documentation.Any idea where I can find some?
Try this code
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"something" ofType:#"mp4"]]];
[self.moviePlayer.view setFrame:CGRectMake(0, 0, 320, 320)];
[self.moviePlayer play];
[self.view addSubview:self.moviePlayer.view];
self.movieplayer is an instance of MPMoviePlayerController (not MPMoviePlayerViewController). In my experience it's important to declare it as a property (like so: #property (strong, nonatomic) MPMoviePlayerController *moviePlayer;) rather than a simple ivar, because sometimes it just doesn't work if it's an ivar
setting the frame is also important, because if we don't set it, the video will not appear at all. The frame can be anything as long as what you define is within the bounds of your view
Important: As above, when defining the URL use NSURL's URLWithString method if you want to access the file through a network and use NSURL's fileUrlWithPath if you have the file locally!

Generic "help" view which is accessible from all views in uinavigationView

Assuming an application has many views pushed to a uinavigationViewController, each view is different in content.
since the elements in the app are complex, I would like to show a small help view for specific views or elements in a specific view.
Imagine a "?" button that when pressed on will pop a new view in the center of the screen, playing youtube help video, or just a textual HTML loaded from a remote server.
Question: what is the best strategy for doing such a thing?
where should I place this code (App Delegate?)
if so, how would I call it from other views (with URL Parameter)
-(void)showHelpView:(NSString *)theURLString{
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)];
//webView.delegate= self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:theURLString]]];
[window addSubview:webView];
[window makeKeyAndVisible];
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
}
I'd prefer using pseudo-modal views. So that you create view every time, and add it on top of current window. I've used this approach for OAuth 2.0 authorisation popup in my last app.
Basically you create custom UIViewController subclass, provide custom initialisator, such as, for example:
// - (id) initWithURL: (URL*)url {
// ...
// self.url = url;
// ...
// return self;
PseudoModalViewController* pmvc = [[PseudoModalViewController alloc] initWithURL:#"http://www.google.com/"];
After you've created view you add it on top of current window:
UIWindow* window = [[UIApplication sharedApplication] keyWindow];
if(!window)
{
window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
}
[window addSubview:pmvc.view];
In, for example, viewDidLoad you load url obtained in initialisator:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}
You may even design UI in Interface Builer for that. As a last piece I'd recommend add to include full screen transparent background view to ensure that all views below are disabled.
Oh, almost forgot, you hide that view with just a simple [self.view removeFromSuperview]. Don't forget to provide correct memory management for that view (i.e. release it in time, etc).

Initiate self.window in appDelegate init method

I'm a web developer creating an Apache Cordova application so my knowledge with Objective-C is very little. Everything is going fine until i try to supplement the splash screen with a video. It sort of does it, but not fully.. It starts with displaying the Default.png followed by the SplashScreenLoader. It then actually plays the video and I know this because the audio is emitted, but the video layer isn't shown.
What I've found out is that the self.window or self.viewController are both defined in didFinishLaunchingWithOptions, so they don't exist in the - (id) init method. Therefore I can't find a way to place it on top of the loading splash.
My init method currently looks like this in AppDelegate.m:
- (id) init {
NSString *moviePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Splash_v1.mp4"];
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
MPMoviePlayerController* moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL: movieURL];
moviePlayer.controlStyle = MPMovieControlStyleNone;
[moviePlayer.view setFrame: self.window.bounds];
[self.window addSubview:moviePlayer.view];
[self.window makeKeyAndVisible];
[moviePlayer play];
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
[cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
[CDVURLProtocol registerURLProtocol];
return [super init];
}
Here the self.window is null, and I've also attempted to set the self.window with this code:
CGRect screenBounds = [[UIScreen mainScreen] bounds];
self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
...without prevail. It actually sets it, but for the subsequent code it doesn't wanna do it.
So what I'm wondering is, how would I place this video on top of the splash's content, before didFinishLaunchingWithOptions kicks in?
Thanks in advance,
//Peter
So what I'm wondering is, how would I place this video on top of the splash's content, before didFinishLaunchingWithOptions kicks in?
actually, you do that in didFinishLaunchingWithOptions. put this statements in there (in the bolierplate code that Xcode generates for you, you should already have a call to makeKeyAndVisible, so just complement it):
[self.window addSubview:moviePlayer.view];
[self.window makeKeyAndVisible];
having previously instantiated your moviePlayer.
One way to avoid the blank screen could be this:
create a UIImageView containing your Default.png image;
display such UIImageView by adding it to your self.window as a subview (this will create no black screen effect);
initialize your player (I assume it takes some time, hence the black screen) and add it below the UIImageView;
when the player is ready (viewDidLoad) push it on top of the UIImageView.
Finally, I don't know how your player will signal the end of the video play, but I assume you have some delegate method; make you appDelegate be also your player delegate and from there, remove UIImageView and player from self.window and add you other view to self.window.
Hope this helps.
EDIT:
This is a rough sketch of what I would try and do in your app delegate appDidFinishLaunching:
self.moviePlayer = <INIT MOVIEW PLAYER CONTROLLER>
self.backgroundImage = <INIT UIImageView with Default.png>
[self.window addSubview:self.moviePlayer.view];
[self.window addSubview:self.backgroundImage];
[self.window makeKeyAndVisible];
In your movie Player viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
...
[self.view.superview addSubview:self.view]; //-- this will just move the player view to the top
...
}
If that helps anyone else, I had the same issue which was resolved by moving '[self.window makeKeyAndVisible];' above the subview like this, so in appdelegate.m:
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
myView.backgroundColor = [UIColor blueColor];
[self.window makeKeyAndVisible];
[self.window addSubview:myView];
This works fine, but if I swap the last two statements around, the subview does not display.

Unable to play local video from iPhone

I'm having trouble playing a video on the iPhone. I have a file in the app bundle and I am trying to play it in a MPMoviePlayerController but it is just displaying a black screen. This is the following code:
-(UIView*)createVideoPlayerOfWidth:(CGFloat)width
{
// The width for one of these can be half of the max width
//CGFloat widthAndHeight = width / 2.0f;
// TODO: Create a video player
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"myVideo" ofType:#"mov"]];
MPMoviePlayerController *playerController = [[MPMoviePlayerController alloc] initWithContentURL:url];
[playerController prepareToPlay];
[playerController setShouldAutoplay:NO];
[playerController setScalingMode:MPMovieScalingModeAspectFit];
[playerController setControlStyle:MPMovieControlStyleEmbedded];
[playerController setRepeatMode:MPMovieRepeatModeNone];
// Resize the thumbnail of the video
[[playerController view] setFrame:CGRectMake(0, 0, width, width)];
return [playerController view];
}
It is returning a valid URL (pathForResource would return nil if it couldn't find the file). I am displaying it to the screen by just adding a subView (the view returned by the function) to a scroll view. I've been trying to solve this for ages now and am getting nowhere. Any help is much appreciated.
Thanks!
Make sure you are retaining a reference to the MPMoviePlayerController instance:
If this is an ARC project, then playerController will be destroyed when createVideoPlayerOfWidth returns, and your video probably won't play. You should store the player in a strong instance variable or property.
You could add something like this to the top of your view controller file:
#interface MyViewController ()
#property (nonatomic,retain) MPMoviePlayerController *player;
#end
And insert this after you create the MPMoviewPlayerController instance:
self.player = playerController;
If you're not using ARC, this is probably not the problem, but you should still keep a reference in an instance variable, so that you can release it later.

load data into a UIWebView created programmatically

I'm setting up a ViewController that will hold a couple of UIViews, including UIWebView
I'm creating and adding those Views programmatically in the viewDidLoad method.
Is this approach satisfactory? or am I doing something too expensive for the hardware.
and how do I load new data into a WebView that was created in the ViewDidLoad method.
I have a properly of type UIWebView, then in the ViewDidLoad i do:
detailsView = [[UIWebView alloc] initWithFrame:CGRectMake(500, 0, 512, 768)];
and this does not seem to work:
- (void)loadDetailedContent:(NSString *)s
{
[detailsView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
[detailsView reload];
}
Waiting for your reply, thank you in advance
You can certainly create and add subviews in your viewController's viewDidLoad programmatically, but you'll have to remember to call addSubview if you want them to appear on the screen.
- (void)viewDidLoad
{
[super viewDidLoad];
detailsView = [[UIWebView alloc] initWithFrame:CGRectMake(500, 0, 512, 768)];
[self.view addSubview:detailsView];
}
As for your second question about loading data into your webview, there is no need to call reload immediately after calling loadRequest:.
- (void)loadDetailedContent:(NSString *)s
{
[detailsView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
}