Skip to content

Commit

Permalink
Merge branch 'release/2.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
SoneeJohn committed Nov 8, 2018
2 parents 3fe1f27 + 4ac5847 commit 995e3f8
Show file tree
Hide file tree
Showing 21 changed files with 586 additions and 39 deletions.
4 changes: 2 additions & 2 deletions .jazzy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ source_directory: XCDYouTubeKit
framework_root: .
umbrella_header: XCDYouTubeKit/XCDYouTubeKit.h
module: XCDYouTubeKit
module_version: 2.6.1
module_version: 2.7.0

author: Cédric Luthi
author_url: https://twitter.com/0xced

readme: README.md
github_url: https://github.com/0xced/XCDYouTubeKit
github_file_prefix: https://github.com/0xced/XCDYouTubeKit/tree/2.6.1/XCDYouTubeKit
github_file_prefix: https://github.com/0xced/XCDYouTubeKit/tree/2.7.0/XCDYouTubeKit
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#### Version 2.7.0

* Add the ability assign cookies via `-[XCDYouTubeClient getVideoWithIdentifier:cookies:completionHandler:]` & `initWithVideoIdentifier:cookies:languageIdentifier:`
* Add the ability to fetch videos allowed to be watched on youtube only (#315, #309)
* Deprecated `XCDYouTubeVideoPlayerViewController` (#157)
* Fixed internal JavaScript exception (#375, #397)

#### Version 2.6.1

* Adaptation to YouTube API change. (#406)
Expand Down
60 changes: 41 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ XCDYouTubeKit is available through CocoaPods and Carthage.
CocoaPods:

```ruby
pod "XCDYouTubeKit", "~> 2.6"
pod "XCDYouTubeKit", "~> 2.7"
```

Carthage:

```objc
github "0xced/XCDYouTubeKit" ~> 2.6
github "0xced/XCDYouTubeKit" ~> 2.7
```

Alternatively, you can manually use the provided static library or dynamic framework. In order to use the static library, you must:
Expand All @@ -54,7 +54,45 @@ These steps will ensure that `#import <XCDYouTubeKit/XCDYouTubeKit.h>` will work

XCDYouTubeKit is [fully documented](http://cocoadocs.org/docsets/XCDYouTubeKit/).

### iOS only
### iOS 8.0+ & tvOS (AVPlayerViewController)

```objc
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
[self presentViewController:playerViewController animated:YES completion:nil];

__weak AVPlayerViewController *weakPlayerViewController = playerViewController;
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoIdentifier completionHandler:^(XCDYouTubeVideo * _Nullable video, NSError * _Nullable error) {
if (video)
{
NSDictionary *streamURLs = video.streamURLs;
NSURL *streamURL = streamURLs[XCDYouTubeVideoQualityHTTPLiveStreaming] ?: streamURLs[@(XCDYouTubeVideoQualityHD720)] ?: streamURLs[@(XCDYouTubeVideoQualityMedium360)] ?: streamURLs[@(XCDYouTubeVideoQualitySmall240)];
weakPlayerViewController.player = [AVPlayer playerWithURL:streamURL];
[weakPlayerViewController.player play];
}
else
{
[self dismissViewControllerAnimated:YES completion:nil];
}
}];
```
### iOS, tvOS and macOS
```objc
NSString *videoIdentifier = @"9bZkp7q19f0"; // A 11 characters YouTube video identifier
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoIdentifier completionHandler:^(XCDYouTubeVideo *video, NSError *error) {
if (video)
{
// Do something with the `video` object
}
else
{
// Handle error
}
}];
```

### iOS 8.0

On iOS, you can use the class `XCDYouTubeVideoPlayerViewController` the same way you use a `MPMoviePlayerViewController`, except you initialize it with a YouTube video identifier instead of a content URL.

Expand Down Expand Up @@ -89,22 +127,6 @@ XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVid
[videoPlayerViewController.moviePlayer play];
```
### iOS, tvOS and macOS
```objc
NSString *videoIdentifier = @"9bZkp7q19f0"; // A 11 characters YouTube video identifier
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoIdentifier completionHandler:^(XCDYouTubeVideo *video, NSError *error) {
if (video)
{
// Do something with the `video` object
}
else
{
// Handle error
}
}];
```

See the demo project for more sample code.
## Logging
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2.6.1;
CURRENT_PROJECT_VERSION = 2.7.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
Expand Down Expand Up @@ -804,7 +804,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 2.6.1;
CURRENT_PROJECT_VERSION = 2.7.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Binary file added XCDYouTubeKit Tests/Cookies/adultUserCookieData
Binary file not shown.
Binary file added XCDYouTubeKit Tests/Cookies/minorUserCookieData
Binary file not shown.
3 changes: 2 additions & 1 deletion XCDYouTubeKit Tests/XCDYouTubeKitTestCase.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ @interface XCDYouTubeKitTestCase ()
@end

static NSString *const offlineSuffix = @"_offline";
static NSString *const onlineSuffix = @"_online";

@implementation XCDYouTubeKitTestCase

Expand Down Expand Up @@ -68,7 +69,7 @@ - (void) setUpTestWithSelector:(SEL)selector
}
else
{
if (onlineTests)
if (onlineTests || [testName hasSuffix:onlineSuffix])
return;

self.cassetteURL = [[NSBundle bundleForClass:self.class] URLForResource:testName withExtension:@"json" subdirectory:[@"Cassettes" stringByAppendingPathComponent:NSStringFromClass(self.class)]];
Expand Down
220 changes: 218 additions & 2 deletions XCDYouTubeKit Tests/XCDYouTubeProtectedVideosTestCase.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,141 @@
#import <XCDYouTubeKit/XCDYouTubeClient.h>

@interface XCDYouTubeProtectedVideosTestCase : XCDYouTubeKitTestCase
extern NSArray <NSHTTPCookie *>* XCDYouTubeProtectedVideosAdultUserCookies(void);
extern NSArray <NSHTTPCookie *>* XCDYouTubeProtectedVideosMinorUserCookies(void);
@end

@implementation XCDYouTubeProtectedVideosTestCase

NSArray <NSHTTPCookie *>* XCDYouTubeProtectedVideosMinorUserCookies()
{
NSURL *cookieURL = [[NSBundle bundleForClass:[XCDYouTubeProtectedVideosTestCase class]]URLForResource:@"minorUserCookieData" withExtension:nil subdirectory:@"Cookies"];

NSCAssert(cookieURL != nil, @"Cookie data could not be found!");
NSData *cookieData = [NSData dataWithContentsOfURL:cookieURL];
NSCAssert(cookieData != nil, @"Cookie data could not be found!");
NSArray <NSHTTPCookie *>*cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookieData];
NSCAssert(cookies.count != 0, @"No cookies found!");
return cookies;
}

NSArray <NSHTTPCookie *>* XCDYouTubeProtectedVideosAdultUserCookies()
{
NSURL *cookieURL = [[NSBundle bundleForClass:[XCDYouTubeProtectedVideosTestCase class]]URLForResource:@"adultUserCookieData" withExtension:nil subdirectory:@"Cookies"];

NSCAssert(cookieURL != nil, @"Cookie data could not be found!");
NSData *cookieData = [NSData dataWithContentsOfURL:cookieURL];
NSCAssert(cookieData != nil, @"Cookie data could not be found!");
NSArray <NSHTTPCookie *>*cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookieData];
NSCAssert(cookies.count != 0, @"No cookies found!");
return cookies;
}

- (void) testAgeRestrictedVideoThatRequiresCookiesWithAdultUserCookies_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"vhG9_yBJmVE" cookies:XCDYouTubeProtectedVideosAdultUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
XCTAssertNotNil(video.expirationDate);
XCTAssertNotNil(video.thumbnailURL);
XCTAssertTrue(video.streamURLs.count > 0);
XCTAssertTrue(video.duration > 0);
[video.streamURLs enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSURL *streamURL, BOOL *stop)
{
XCTAssertTrue([streamURL.query rangeOfString:@"signature="].location != NSNotFound);
}];
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void) testAgeRestrictedVideoThatRequiresCookiesWithAdultUserCookiesIsPlayable_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"vhG9_yBJmVE" cookies:XCDYouTubeProtectedVideosAdultUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
XCTAssertNotNil(video.expirationDate);
XCTAssertNotNil(video.thumbnailURL);
XCTAssertTrue(video.streamURLs.count > 0);
XCTAssertTrue(video.duration > 0);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:video.streamURLs[@(XCDYouTubeVideoQualityMedium360)]];
request.HTTPMethod = @"HEAD";
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError)
{
XCTAssertEqual([(NSHTTPURLResponse *)response statusCode], 200);
[expectation fulfill];
}];

[dataTask resume];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void) testAgeRestrictedVideoThatRequiresCookiesWithMinorUserCookies_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"vhG9_yBJmVE" cookies:XCDYouTubeProtectedVideosMinorUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
XCTAssertNotNil(video.expirationDate);
XCTAssertNotNil(video.thumbnailURL);
XCTAssertTrue(video.streamURLs.count > 0);
XCTAssertTrue(video.duration > 0);
[video.streamURLs enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSURL *streamURL, BOOL *stop)
{
XCTAssertTrue([streamURL.query rangeOfString:@"signature="].location != NSNotFound);
}];
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void) testAgeRestrictedVideoThatRequiresCookiesWithMinortUserCookiesIsPlayable_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"vhG9_yBJmVE" cookies:XCDYouTubeProtectedVideosMinorUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
XCTAssertNotNil(video.expirationDate);
XCTAssertNotNil(video.thumbnailURL);
XCTAssertTrue(video.streamURLs.count > 0);
XCTAssertTrue(video.duration > 0);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:video.streamURLs[@(XCDYouTubeVideoQualityMedium360)]];
request.HTTPMethod = @"HEAD";
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError)
{
XCTAssertEqual([(NSHTTPURLResponse *)response statusCode], 200);
[expectation fulfill];
}];

[dataTask resume];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void) testAgeRestrictedVideoThatRequiresCookiesWithoutCookies
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"vhG9_yBJmVE" completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNotNil(error);
XCTAssertNil(video);
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:5 handler:nil];
}

- (void) testAgeRestrictedVideo
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
Expand Down Expand Up @@ -153,10 +284,10 @@ - (void) testDASHAudioWithRateBypassIsPlayable
[self waitForExpectationsWithTimeout:5 handler:nil];
}

- (void) testAgeRestrictedVEVOVideo
- (void) testAgeRestrictedVEVOVideoWithAdultUserCookies_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"07FYdnEawAQ" completionHandler:^(XCDYouTubeVideo *video, NSError *error)
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"07FYdnEawAQ" cookies:XCDYouTubeProtectedVideosAdultUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
Expand All @@ -170,6 +301,91 @@ - (void) testAgeRestrictedVEVOVideo
}];
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void) testAgeRestrictedVEVOVideoWithAdultUserCookiesIsPlayable_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"07FYdnEawAQ" cookies:XCDYouTubeProtectedVideosAdultUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
XCTAssertNotNil(video.expirationDate);
XCTAssertNotNil(video.thumbnailURL);
XCTAssertTrue(video.streamURLs.count > 0);
XCTAssertTrue(video.duration > 0);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:video.streamURLs[@(XCDYouTubeVideoQualityMedium360)]];
request.HTTPMethod = @"HEAD";
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError)
{
XCTAssertEqual([(NSHTTPURLResponse *)response statusCode], 200);
[expectation fulfill];
}];

[dataTask resume];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void) testAgeRestrictedVEVOVideoWithMinorUserCookies_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"07FYdnEawAQ" cookies:XCDYouTubeProtectedVideosMinorUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
XCTAssertNotNil(video.expirationDate);
XCTAssertNotNil(video.thumbnailURL);
XCTAssertTrue(video.streamURLs.count > 0);
XCTAssertTrue(video.duration > 0);
[video.streamURLs enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSURL *streamURL, BOOL *stop)
{
XCTAssertTrue([streamURL.query rangeOfString:@"signature="].location != NSNotFound);
}];
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void) testAgeRestrictedVEVOVideoWithMinorUserCookiesIsPlayable_online
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"07FYdnEawAQ" cookies:XCDYouTubeProtectedVideosMinorUserCookies() completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNil(error);
XCTAssertNotNil(video.title);
XCTAssertNotNil(video.expirationDate);
XCTAssertNotNil(video.thumbnailURL);
XCTAssertTrue(video.streamURLs.count > 0);
XCTAssertTrue(video.duration > 0);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:video.streamURLs[@(XCDYouTubeVideoQualityMedium360)]];
request.HTTPMethod = @"HEAD";
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError)
{
XCTAssertEqual([(NSHTTPURLResponse *)response statusCode], 200);
[expectation fulfill];
}];

[dataTask resume];
}];

[self waitForExpectationsWithTimeout:30 handler:nil];
}

- (void)testAgeRestrictedVEVOVideoWithoutCookies
{
__weak XCTestExpectation *expectation = [self expectationWithDescription:@""];
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:@"07FYdnEawAQ" completionHandler:^(XCDYouTubeVideo *video, NSError *error)
{
XCTAssertNotNil(error);
XCTAssertNil(video);
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:5 handler:nil];
}

Expand Down
Loading

0 comments on commit 995e3f8

Please sign in to comment.