Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add arc warning, and more experimental changes to work better. seems …

…that simulating an old browser helps a lot.
  • Loading branch information...
commit 7713143e2e96ad1d9ec888b9e0b276c94cf99eac 1 parent 1b75259
@steipete authored
Showing with 73 additions and 14 deletions.
  1. +69 −14 PSYouTubeExtractor.m
  2. +4 −0 PSYouTubeView.m
View
83 PSYouTubeExtractor.m
@@ -8,6 +8,11 @@
#import "PSYouTubeExtractor.h"
#import <UIKit/UIKit.h>
+#import <objc/runtime.h>
+
+#if ! __has_feature(objc_arc)
+#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag
+#endif
@interface PSYouTubeExtractor() <UIWebViewDelegate> {
BOOL testedDOM_;
@@ -28,13 +33,13 @@ @implementation PSYouTubeExtractor
@synthesize youTubeURL = youTubeURL_;
-#define kMaxNumberOfRetries 4 // numbers of retries
-#define kWatchdogDelay 3.f // seconds we wait for the DOM
+#define kMaxNumberOfRetries 2 // numbers of retries
+#define kWatchdogDelay 5.f // seconds we wait for the DOM
#define kExtraDOMDelay 3.f // if DOM doesn't load, wait for some extra time
// uncomment to enable logging
-//#define PSLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
-#define PSLog(fmt, ...)
+#define PSLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
+//#define PSLog(fmt, ...)
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSObject
@@ -56,6 +61,13 @@ - (void)dealloc {
webView_.delegate = nil;
}
++ (void)initialize {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ [NSMutableURLRequest setupUserAgentOverwrite];
+ });
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Static
@@ -68,11 +80,12 @@ + (PSYouTubeExtractor *)extractorForYouTubeURL:(NSURL *)youTubeURL success:(void
#pragma mark - Public
- (void)cleanup_ {
- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(DOMLoaded_) object:nil]; // cancel watchdog
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
successBlock_ = nil;
failureBlock_ = nil;
selfReference_ = nil;
[webView_ stopLoading];
+ webView_.delegate = nil;
webView_ = nil;
retryCount_ = 0;
domWaitCounter_ = 0;
@@ -92,25 +105,35 @@ - (BOOL)cancel {
// very possible that the DOM isn't really loaded after all or sth failed. Try to load website again.
- (BOOL)doRetry_ {
- if (retryCount_ <= kMaxNumberOfRetries + 1) {
+ // stop if we don't have a selfReference. (cleanup was called)
+ if (selfReference_ && (retryCount_ <= kMaxNumberOfRetries + 1)) {
retryCount_++;
domWaitCounter_ = 0;
PSLog(@"Trying to load page...");
webView_.delegate = nil;
webView_ = [[UIWebView alloc] init];
webView_.delegate = self;
+
+ // we fake an old version of the iOS browser to get a correct response.
+ // else request does seem to fail on iOS 5 upwards unless we're on an actual iPhone device. Weird.
+ //NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16", @"UserAgent", nil];
+ //[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
+
[webView_ loadRequest:[NSURLRequest requestWithURL:youTubeURL_]];
- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(DOMLoaded_) object:nil];
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
return YES;
}
return NO;
}
- (void)DOMLoaded_ {
- PSLog(@"DOMLoaded_ / watchdog hit");
+ // ugly hack to see what's going on.
+ //[[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] view] addSubview:webView_];
+ //webView_.frame = [UIScreen mainScreen].bounds;
// figure out if we can extract the youtube url!
NSString *youTubeMP4URL = [webView_ stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('video')[0].getAttribute('src')"];
+ PSLog(@"testing dom. query: %@", youTubeMP4URL);
if ([youTubeMP4URL hasPrefix:@"http"]) {
// probably ok
@@ -120,9 +143,9 @@ - (void)DOMLoaded_ {
}
[self cleanup_];
}else {
- if (domWaitCounter_ < kExtraDOMDelay * 2) {
+ if (domWaitCounter_ < kExtraDOMDelay * 4) {
domWaitCounter_++;
- [self performSelector:@selector(DOMLoaded_) withObject:nil afterDelay:0.5f]; // try every 0.5 sec
+ [self performSelector:@selector(DOMLoaded_) withObject:nil afterDelay:0.25f]; // try often!
return;
}
@@ -141,12 +164,22 @@ - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)
NSURL *url = [aRequest URL];
NSString *scheme = [url scheme];
+ /*
+ // we fake an old version of the iOS browser to get a correct response.
+ // else request does seem to fail on iOS 5 upwards unless we're on an actual iPhone device. Weird.
+ NSMutableURLRequest *request = (NSMutableURLRequest *)aRequest;
+ if ([request respondsToSelector:@selector(setValue:forHTTPHeaderField:)]) {
+ [request setValue:@"Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16" forHTTPHeaderField:@"User-Agent"];
+ }*/
+
// Check for DOM load message
if ([scheme isEqualToString:@"x-sswebview"]) {
NSString *host = [url host];
if ([host isEqualToString:@"dom-loaded"]) {
PSLog(@"DOM load detected!");
- [self DOMLoaded_];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self DOMLoaded_];
+ });
}
return NO;
}
@@ -172,6 +205,10 @@ - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)
// With some guidance of SSToolKit this was pretty easy. Thanks Sam!
- (void)webViewDidFinishLoad:(UIWebView *)webView {
+ if (!selfReference_) {
+ return;
+ }
+
PSLog(@"webViewDidFinishLoad");
// Check DOM
@@ -185,12 +222,11 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView {
}
// add watchdog in case DOM never get initialized
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(DOMLoaded_) object:nil];
[self performSelector:@selector(DOMLoaded_) withObject:nil afterDelay:kWatchdogDelay];
}
-- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
- PSLog(@"didFailLoadWithError");
-
+- (void)DOMFailed_:(NSError *)error {
if (![self doRetry_]) {
if (failureBlock_) {
failureBlock_(error);
@@ -199,4 +235,23 @@ - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
}
}
+- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
+ if (!selfReference_) {
+ return;
+ }
+
+ NSURL *errorURL = [error.userInfo objectForKey:@"NSErrorFailingURLKey"];
+ if ([[errorURL absoluteString] rangeOfString:@"poswidget"].length) {
+ PSLog(@"ignoring error: %@", error);
+ return; // ignore those errors
+ }
+
+ PSLog(@"didFailLoadWithError: %@", error);
+
+ // give system a little bit more time, may be an irrelevant error
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
+ [self performSelector:@selector(DOMFailed_:) withObject:error afterDelay:kWatchdogDelay/3];
+}
+
@end
+
View
4 PSYouTubeView.m
@@ -9,6 +9,10 @@
#import "PSYouTubeView.h"
#import "PSYouTubeExtractor.h"
+#if ! __has_feature(objc_arc)
+#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag
+#endif
+
@interface PSYouTubeView() {
BOOL showNativeFirst_;
PSYouTubeExtractor *extractor_;
Please sign in to comment.
Something went wrong with that request. Please try again.