From ef5dd5d6b2dc494c7de70a2d01dd482d2734d1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Wed, 12 Sep 2018 19:57:52 +0200 Subject: [PATCH 01/28] Bump version number --- SRGContentProtection.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SRGContentProtection.xcodeproj/project.pbxproj b/SRGContentProtection.xcodeproj/project.pbxproj index d272efc..5e213e8 100644 --- a/SRGContentProtection.xcodeproj/project.pbxproj +++ b/SRGContentProtection.xcodeproj/project.pbxproj @@ -639,7 +639,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.2; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -765,7 +765,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -953,7 +953,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.2; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -1010,7 +1010,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; From 25943fb12293c1c9c85638824f2134ae31ca075d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Wed, 19 Sep 2018 18:39:05 +0200 Subject: [PATCH 02/28] Add fastlane test --- .gitignore | 3 +++ fastlane/Fastfile | 46 ++++++++++++++++++++++++++++++++++++++++++++++ fastlane/README.md | 29 +++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 fastlane/Fastfile create mode 100644 fastlane/README.md diff --git a/.gitignore b/.gitignore index 1ad59ad..61ad343 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ archive build Carthage + +fastlane/report.xml +fastlane/test_output \ No newline at end of file diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 0000000..b005e49 --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,46 @@ +# Customise this file, documentation can be found here: +# https://github.com/fastlane/fastlane/tree/master/fastlane/docs +# All available actions: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Actions.md +# can also be listed using the `fastlane actions` command + +# Change the syntax highlighting to Ruby +# All lines starting with a # are ignored when running `fastlane` + +# This is the minimum version number required. +fastlane_version "1.95.0" + +default_platform :ios + +platform :ios do + before_all do |lane| + ensure_git_status_clean + + Dir.chdir("..") do + sh "make bootstrap" + end + end + + desc "Run library tests" + lane :test do + scan( + scheme: "SRGContentProtection", + clean: true + ) + end + + after_all do |lane| + reset_git_repo(skip_clean: true) + end + + error do |lane, exception| + clean_build_artifacts + reset_git_repo(skip_clean: true, force: true) + end +end + + +# More information about multiple platforms in fastlane: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md +# All available actions: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Actions.md + +# fastlane reports which actions are used +# No personal data is recorded. Learn more at https://github.com/fastlane/enhancer diff --git a/fastlane/README.md b/fastlane/README.md new file mode 100644 index 0000000..cd66005 --- /dev/null +++ b/fastlane/README.md @@ -0,0 +1,29 @@ +fastlane documentation +================ +# Installation + +Make sure you have the latest version of the Xcode command line tools installed: + +``` +xcode-select --install +``` + +Install _fastlane_ using +``` +[sudo] gem install fastlane -NV +``` +or alternatively using `brew cask install fastlane` + +# Available Actions +## iOS +### ios test +``` +fastlane ios test +``` +Run library tests + +---- + +This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. +More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). +The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). From f97db3b8d5763e3b2b7fc4e602c24f619c85872a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Tue, 11 Sep 2018 14:59:47 +0200 Subject: [PATCH 03/28] Add SRG Diagnostics --- Cartfile | 1 + Cartfile.resolved | 3 ++- SRGContentProtection.xcodeproj/project.pbxproj | 12 ++++++++++++ docs/README.md | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Cartfile b/Cartfile index 4cdbdd5..7429943 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1,2 @@ +github "SRGSSR/srgdiagnostics-ios" "793ded847636b8c87d79542daf8765f50e567559" github "SRGSSR/srgnetwork-ios" "0.2" \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index 7bd70ea..7429943 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1,2 @@ -github "SRGSSR/srgnetwork-ios" "0.2" +github "SRGSSR/srgdiagnostics-ios" "793ded847636b8c87d79542daf8765f50e567559" +github "SRGSSR/srgnetwork-ios" "0.2" \ No newline at end of file diff --git a/SRGContentProtection.xcodeproj/project.pbxproj b/SRGContentProtection.xcodeproj/project.pbxproj index 5e213e8..ec2b9f5 100644 --- a/SRGContentProtection.xcodeproj/project.pbxproj +++ b/SRGContentProtection.xcodeproj/project.pbxproj @@ -33,6 +33,11 @@ 6FB74D782101D5D600E2D365 /* FairPlayResourceLoaderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FB74D752101D5D600E2D365 /* FairPlayResourceLoaderTestCase.m */; }; 6FB74D7B2101D69F00E2D365 /* SRGNetwork.framework in Copy Files */ = {isa = PBXBuildFile; fileRef = 6F0432BC21006E7A002B090A /* SRGNetwork.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6FBCA7412109A9F4004CD02D /* AkamaiTokenTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FBCA7402109A9F4004CD02D /* AkamaiTokenTestCase.m */; }; + 6FBF24312147F3ED00E576A2 /* SRGDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; }; + 6FBF24322147F4BC00E576A2 /* SRGDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; }; + 6FBF24332147F4C200E576A2 /* SRGDiagnostics.framework in Copy Files */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 6FBF24342147F4C900E576A2 /* SRGDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; }; + 6FBF24352147F4C900E576A2 /* SRGDiagnostics.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6FD810F420FCB58500F250B9 /* AVURLAsset+SRGContentProtection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FD810F220FCB58500F250B9 /* AVURLAsset+SRGContentProtection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6FD810F520FCB58500F250B9 /* AVURLAsset+SRGContentProtection.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD810F320FCB58500F250B9 /* AVURLAsset+SRGContentProtection.m */; }; 6FD8110120FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FD810FF20FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h */; }; @@ -75,6 +80,7 @@ dstSubfolderSpec = 10; files = ( 6F0432BF21007340002B090A /* SRGNetwork.framework in Embed Frameworks */, + 6FBF24352147F4C900E576A2 /* SRGDiagnostics.framework in Embed Frameworks */, 6F8A940420FDD01B00AA6434 /* SRGContentProtection.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -86,6 +92,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 6FBF24332147F4C200E576A2 /* SRGDiagnostics.framework in Copy Files */, 6FB74D7B2101D69F00E2D365 /* SRGNetwork.framework in Copy Files */, ); name = "Copy Files"; @@ -121,6 +128,7 @@ 6FB74D752101D5D600E2D365 /* FairPlayResourceLoaderTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FairPlayResourceLoaderTestCase.m; sourceTree = ""; }; 6FB74D762101D5D600E2D365 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6FBCA7402109A9F4004CD02D /* AkamaiTokenTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AkamaiTokenTestCase.m; sourceTree = ""; }; + 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SRGDiagnostics.framework; path = Carthage/Build/iOS/SRGDiagnostics.framework; sourceTree = ""; }; 6FCBFEF8210B578B006BC355 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 6FCBFEFA210B57BD006BC355 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 6FCBFEFB210B57BD006BC355 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; @@ -148,6 +156,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 6FBF24312147F3ED00E576A2 /* SRGDiagnostics.framework in Frameworks */, 6F0432BD21006E7A002B090A /* SRGNetwork.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -157,6 +166,7 @@ buildActionMask = 2147483647; files = ( 6F0432BE21007340002B090A /* SRGNetwork.framework in Frameworks */, + 6FBF24342147F4C900E576A2 /* SRGDiagnostics.framework in Frameworks */, 6F8A940320FDD01B00AA6434 /* SRGContentProtection.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -165,6 +175,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 6FBF24322147F4BC00E576A2 /* SRGDiagnostics.framework in Frameworks */, 6FE91E7B2108A36A001B5E8F /* SRGNetwork.framework in Frameworks */, 6FB74D6C2101D4D200E2D365 /* SRGContentProtection.framework in Frameworks */, ); @@ -282,6 +293,7 @@ 6F8A945521006A9E00AA6434 /* Frameworks */ = { isa = PBXGroup; children = ( + 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */, 6F0432BC21006E7A002B090A /* SRGNetwork.framework */, ); name = Frameworks; diff --git a/docs/README.md b/docs/README.md index f8e58f2..732e0b7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -30,6 +30,7 @@ For more information about Carthage and its use, refer to the [official document The library requires the following frameworks to be added to any target requiring it: * `SRGContentProtection`: The content protection library framework. +* `SRGDiagnostics`: Framework for collecting diagnostic information. * `SRGNetwork`: A networking framework. ### Dynamic framework integration From d52511462b2dcec8440b33384894239020b89c9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Tue, 11 Sep 2018 15:36:19 +0200 Subject: [PATCH 04/28] Provide mechanism to associate an optional context --- .../AVURLAsset+SRGContentProtection.h | 21 ++++++++- .../AVURLAsset+SRGContentProtection.m | 24 +++++++--- .../SRGAkamaiAssetResourceLoaderDelegate.h | 2 +- .../SRGAkamaiAssetResourceLoaderDelegate.m | 44 +++++++------------ .../SRGAssetResourceLoaderDelegate.h | 26 ++++++++--- .../SRGAssetResourceLoaderDelegate.m | 43 ++++++++++++++++++ .../SRGFairPlayAssetResourceLoaderDelegate.h | 2 +- .../SRGFairPlayAssetResourceLoaderDelegate.m | 29 ++++-------- .../project.pbxproj | 4 ++ 9 files changed, 134 insertions(+), 61 deletions(-) create mode 100644 Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.m diff --git a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h index a1f6ce5..61b3cc9 100644 --- a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h +++ b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h @@ -8,6 +8,11 @@ NS_ASSUME_NONNULL_BEGIN +/** + * Optional user information keys which can be used to provide more context information. + */ +OBJC_EXPORT NSString * const SRGContentProtectionURNKey; // The URN of the content being played, if any (`NSString`). + /** * `AVURLAsset` extensions for protected content playback. To play a protected content: * - Create an asset using the `+srg_assetWithURL:certificateURL:` method. @@ -21,7 +26,14 @@ NS_ASSUME_NONNULL_BEGIN /** * Create an asset supporting standard SRG SSR content protection. * - * @param URL The URL to be played. + * @param URL The URL to be played. + * @param userInfo Dictionary to convey optional context information to the content loader (see keys at the top of this + * file). + */ ++ (instancetype)srg_assetWithURL:(NSURL *)URL userInfo:(nullable NSDictionary *)userInfo; + +/** + * Same as `-srg_assetWithURL:userInfo:`, but without user information dictionary. */ + (instancetype)srg_assetWithURL:(NSURL *)URL; @@ -31,6 +43,13 @@ NS_ASSUME_NONNULL_BEGIN * * @param URL The URL to be played. * @param licenseURL The URL where licenses must be retrieved. + * @param userInfo Dictionary to convey optional context information to the content loader (see keys at the top of this + * file). + */ ++ (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(nullable NSURL *)licenseURL userInfo:(nullable NSDictionary *)userInfo; + +/** + * Same as `-srg_assetWithURL:licenseURL:userInfo:`, but without user information dictionary. */ + (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(nullable NSURL *)licenseURL; diff --git a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m index e888407..5827bc4 100644 --- a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m +++ b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m @@ -11,15 +11,17 @@ #import +NSString * const SRGContentProtectionURNKey = @"SRGContentProtectionURN"; + static void *SRGContentProtectionResourceLoaderDelegateKey = &SRGContentProtectionResourceLoaderDelegateKey; @implementation AVURLAsset (SRGContentProtection) #pragma mark Class methods -+ (instancetype)srg_assetWithURL:(NSURL *)URL resourceLoaderDelegate:(id)resourceLoaderDelegate ++ (instancetype)srg_assetWithURL:(NSURL *)URL resourceLoaderDelegate:(SRGAssetResourceLoaderDelegate *)resourceLoaderDelegate { - NSURL *assetURL = [resourceLoaderDelegate respondsToSelector:@selector(assetURLForURL:)] ? [resourceLoaderDelegate assetURLForURL:URL] : URL; + NSURL *assetURL = resourceLoaderDelegate ? [resourceLoaderDelegate assetURLForURL:URL] : URL; AVURLAsset *asset = [AVURLAsset assetWithURL:assetURL]; objc_setAssociatedObject(asset, SRGContentProtectionResourceLoaderDelegateKey, resourceLoaderDelegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -29,21 +31,33 @@ + (instancetype)srg_assetWithURL:(NSURL *)URL resourceLoaderDelegate:(id resourceLoaderDelegate = nil; + SRGAssetResourceLoaderDelegate *resourceLoaderDelegate = nil; if (licenseURL) { resourceLoaderDelegate = [[SRGFairPlayAssetResourceLoaderDelegate alloc] initWithCertificateURL:licenseURL]; } else if ([URL.host containsString:@"akamai"] && [URL.path.pathExtension isEqualToString:@"m3u8"]) { resourceLoaderDelegate = [[SRGAkamaiAssetResourceLoaderDelegate alloc] init]; } + resourceLoaderDelegate.userInfo = userInfo; + return [self srg_assetWithURL:URL resourceLoaderDelegate:resourceLoaderDelegate]; } ++ (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(NSURL *)licenseURL +{ + return [self srg_assetWithURL:URL licenseURL:licenseURL userInfo:nil]; +} + @end diff --git a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.h b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.h index b354870..d944c33 100644 --- a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.h +++ b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Resource loader delegate for Akamai token-protected streams. */ -@interface SRGAkamaiAssetResourceLoaderDelegate : NSObject +@interface SRGAkamaiAssetResourceLoaderDelegate : SRGAssetResourceLoaderDelegate @end diff --git a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m index f30a797..63215a8 100644 --- a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m +++ b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m @@ -42,7 +42,21 @@ - (instancetype)init return self; } -#pragma mark Common resource loading request processing +#pragma mark Subclassing hooks + +- (NSURL *)assetURLForURL:(NSURL *)URL +{ + /** + * Use non-standard scheme unkwown to AirPlay receivers like the Apple TV. This ensures that the resource + * loader delegate is used (if the resource is simply an HTTP one, the receiver thinks it can handle it, + * and does not call the resource loader delegate). + * + * See https://stackoverflow.com/a/30154884/760435 + */ + NSURLComponents *components = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO]; + components.scheme = [@[ SRGStandardURLSchemePrefix, components.scheme ] componentsJoinedByString:@"+"]; + return components.URL; +} - (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest { @@ -75,33 +89,7 @@ - (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loa return YES; } -#pragma mark SRGAssetResourceLoaderDelegate protocol - -- (NSURL *)assetURLForURL:(NSURL *)URL -{ - /** - * Use non-standard scheme unkwown to AirPlay receivers like the Apple TV. This ensures that the resource - * loader delegate is used (if the resource is simply an HTTP one, the receiver thinks it can handle it, - * and does not call the resource loader delegate). - * - * See https://stackoverflow.com/a/30154884/760435 - */ - NSURLComponents *components = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO]; - components.scheme = [@[ SRGStandardURLSchemePrefix, components.scheme ] componentsJoinedByString:@"+"]; - return components.URL; -} - -- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest -{ - return [self shouldProcessResourceLoadingRequest:loadingRequest]; -} - -- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForRenewalOfRequestedResource:(AVAssetResourceRenewalRequest *)renewalRequest -{ - return [self shouldProcessResourceLoadingRequest:renewalRequest]; -} - -- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest +- (void)didCancelResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest { [self.request cancel]; } diff --git a/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h b/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h index 78990fc..91780f7 100644 --- a/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h +++ b/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h @@ -9,17 +9,33 @@ NS_ASSUME_NONNULL_BEGIN /** - * Resource loader delegate protocol. + * Resource loader abstract base class. */ -@protocol SRGAssetResourceLoaderDelegate - -@optional +@interface SRGAssetResourceLoaderDelegate : NSObject /** - * Return the asset URL to use for a given URL. If not implemented, the original URL will be used. + * Suclasses can override this method to return another URL to use for a given URL. The default implementation returns + * the original URL received as parameter. */ - (NSURL *)assetURLForURL:(NSURL *)URL; +/** + * Subclasses must override this method to process the loading request appropriately. The default implementation does + * nothing and returns `NO`. + */ +- (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest; + +/** + * Subclasses must override this method to respond to a resource having been cancelled. The default implementation does + * nothing. + */ +- (void)didCancelResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest; + +/** + * Optional information associated with the receiver. + */ +@property (nonatomic, nullable) NSDictionary *userInfo; + @end NS_ASSUME_NONNULL_END diff --git a/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.m new file mode 100644 index 0000000..2958512 --- /dev/null +++ b/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.m @@ -0,0 +1,43 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import "SRGAssetResourceLoaderDelegate.h" + +@implementation SRGAssetResourceLoaderDelegate + +#pragma mark Default implementations + +- (NSURL *)assetURLForURL:(NSURL *)URL +{ + return URL; +} + +- (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest +{ + return NO; +} + +- (void)didCancelResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest +{} + +#pragma mark AVAssetResourceLoaderDelegate protocol + +- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest +{ + return [self shouldProcessResourceLoadingRequest:loadingRequest]; +} + +- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForRenewalOfRequestedResource:(AVAssetResourceRenewalRequest *)renewalRequest +{ + return [self shouldProcessResourceLoadingRequest:renewalRequest]; +} + +- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest +{ + [self didCancelResourceLoadingRequest:loadingRequest]; +} + +@end diff --git a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.h b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.h index 0ac91c2..36ef4cc 100644 --- a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.h +++ b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Resource loader delegate for streams encrypted with FairPlay. */ -@interface SRGFairPlayAssetResourceLoaderDelegate : NSObject +@interface SRGFairPlayAssetResourceLoaderDelegate : SRGAssetResourceLoaderDelegate /** * Create an instance retrieving certificates at the specified URL. diff --git a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m index 8626961..42c5fd0 100644 --- a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m +++ b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m @@ -62,8 +62,9 @@ - (instancetype)init #pragma clang diagnostic pop -#pragma mark Common resource loading request processing +#pragma mark Subclassing hooks +// For FairPlay-protected streams, only called on a device - (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest { // About thread-safety considerations: The delegate methods are called from background threads, and though there is @@ -103,6 +104,13 @@ - (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loa return YES; } +- (void)didCancelResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest +{ + [self.request cancel]; +} + +#pragma mark Helpers + - (void)finishLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest withContentKeyContextData:(NSData *)contentKeyContextData error:(NSError *)error { if (contentKeyContextData) { @@ -119,23 +127,4 @@ - (void)finishLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest wit } } -#pragma mark SRGAssetResourceLoaderDelegate protocol - -// For FairPlay-protected streams, only called on a device -- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest -{ - return [self shouldProcessResourceLoadingRequest:loadingRequest]; -} - -// For FairPlay-protected streams, only called on a device -- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForRenewalOfRequestedResource:(AVAssetResourceRenewalRequest *)renewalRequest -{ - return [self shouldProcessResourceLoadingRequest:renewalRequest]; -} - -- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest -{ - [self.request cancel]; -} - @end diff --git a/SRGContentProtection.xcodeproj/project.pbxproj b/SRGContentProtection.xcodeproj/project.pbxproj index ec2b9f5..6e6dddd 100644 --- a/SRGContentProtection.xcodeproj/project.pbxproj +++ b/SRGContentProtection.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ 6FBF24332147F4C200E576A2 /* SRGDiagnostics.framework in Copy Files */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6FBF24342147F4C900E576A2 /* SRGDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; }; 6FBF24352147F4C900E576A2 /* SRGDiagnostics.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 6FBF24372147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FBF24362147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m */; }; 6FD810F420FCB58500F250B9 /* AVURLAsset+SRGContentProtection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FD810F220FCB58500F250B9 /* AVURLAsset+SRGContentProtection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6FD810F520FCB58500F250B9 /* AVURLAsset+SRGContentProtection.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD810F320FCB58500F250B9 /* AVURLAsset+SRGContentProtection.m */; }; 6FD8110120FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FD810FF20FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h */; }; @@ -129,6 +130,7 @@ 6FB74D762101D5D600E2D365 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6FBCA7402109A9F4004CD02D /* AkamaiTokenTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AkamaiTokenTestCase.m; sourceTree = ""; }; 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SRGDiagnostics.framework; path = Carthage/Build/iOS/SRGDiagnostics.framework; sourceTree = ""; }; + 6FBF24362147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SRGAssetResourceLoaderDelegate.m; sourceTree = ""; }; 6FCBFEF8210B578B006BC355 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 6FCBFEFA210B57BD006BC355 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 6FCBFEFB210B57BD006BC355 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; @@ -333,6 +335,7 @@ 6FD810FF20FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h */, 6FD8110020FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.m */, 6FE021DC2119B58800DF6617 /* SRGAssetResourceLoaderDelegate.h */, + 6FBF24362147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m */, 6F8A93D020FDB3D200AA6434 /* SRGFairPlayAssetResourceLoaderDelegate.h */, 6F8A93D120FDB3D200AA6434 /* SRGFairPlayAssetResourceLoaderDelegate.m */, ); @@ -532,6 +535,7 @@ files = ( 6F0EB54720FC8049009C02CF /* NSBundle+SRGContentProtection.m in Sources */, 6F0EB54320FC7FF4009C02CF /* SRGContentProtection.m in Sources */, + 6FBF24372147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m in Sources */, 6FD8110220FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.m in Sources */, 6F7B786B2108A05C001E3BBE /* SRGAkamaiToken.m in Sources */, 6FDE576520FC9DC700719525 /* SRGContentProtectionError.m in Sources */, From fa1993b2c83733ac1114764a10de7a26ed01c0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Tue, 11 Sep 2018 17:06:49 +0200 Subject: [PATCH 05/28] Fill diagnostic report information --- .../AVURLAsset+SRGContentProtection.h | 5 ----- .../AVURLAsset+SRGContentProtection.m | 2 -- .../SRGAkamaiAssetResourceLoaderDelegate.m | 19 +++++++++++++++++ .../SRGFairPlayAssetResourceLoaderDelegate.m | 21 +++++++++++++++++++ Framework/Sources/SRGContentProtection.h | 1 + .../Sources/SRGContentProtectionConstants.h | 12 +++++++++++ .../Sources/SRGContentProtectionConstants.m | 9 ++++++++ .../project.pbxproj | 8 +++++++ 8 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 Framework/Sources/SRGContentProtectionConstants.h create mode 100644 Framework/Sources/SRGContentProtectionConstants.m diff --git a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h index 61b3cc9..a818d87 100644 --- a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h +++ b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h @@ -8,11 +8,6 @@ NS_ASSUME_NONNULL_BEGIN -/** - * Optional user information keys which can be used to provide more context information. - */ -OBJC_EXPORT NSString * const SRGContentProtectionURNKey; // The URN of the content being played, if any (`NSString`). - /** * `AVURLAsset` extensions for protected content playback. To play a protected content: * - Create an asset using the `+srg_assetWithURL:certificateURL:` method. diff --git a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m index 5827bc4..fb72cb0 100644 --- a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m +++ b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m @@ -11,8 +11,6 @@ #import -NSString * const SRGContentProtectionURNKey = @"SRGContentProtectionURN"; - static void *SRGContentProtectionResourceLoaderDelegateKey = &SRGContentProtectionResourceLoaderDelegateKey; @implementation AVURLAsset (SRGContentProtection) diff --git a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m index 63215a8..802f3b4 100644 --- a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m +++ b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m @@ -8,8 +8,11 @@ #import "NSBundle+SRGContentProtection.h" #import "SRGAkamaiToken.h" +#import "SRGContentProtectionConstants.h" #import "SRGContentProtectionError.h" +#import + static NSString * const SRGStandardURLSchemePrefix = @"akamai"; @interface SRGAkamaiAssetResourceLoaderDelegate () @@ -42,6 +45,14 @@ - (instancetype)init return self; } +#pragma mark Getters and setters + +- (SRGDiagnosticInformation *)diagnosticInformation +{ + NSString *URN = self.userInfo[SRGContentProtectionURNKey]; + return URN ? [[[SRGDiagnosticsService serviceWithName:@"SRGPlaybackMetrics"] reportWithName:URN] informationForKey:@"tokenResult"] : nil; +} + #pragma mark Subclassing hooks - (NSURL *)assetURLForURL:(NSURL *)URL @@ -60,6 +71,9 @@ - (NSURL *)assetURLForURL:(NSURL *)URL - (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest { + SRGDiagnosticInformation *diagnosticInformation = [self diagnosticInformation]; + [diagnosticInformation startTimeMeasurementForKey:@"duration"]; + // About thread-safety considerations: The delegate methods are called from background threads, and though there is // no explicit documentation, Apple examples show that completion calls can be made from background threads. There // is probably no need to dispatch any work to the main thread. @@ -82,6 +96,11 @@ - (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loa [loadingRequest.dataRequest respondWithData:data]; [loadingRequest finishLoading]; } + + [diagnosticInformation setURL:URL forKey:@"url"]; + [diagnosticInformation setInteger:HTTPResponse.statusCode forKey:@"httpStatusCode"]; + [diagnosticInformation setString:error.localizedDescription forKey:@"message"]; + [diagnosticInformation stopTimeMeasurementForKey:@"duration"]; }]; [self.request resume]; }]; diff --git a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m index 42c5fd0..6efeabd 100644 --- a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m +++ b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m @@ -7,8 +7,10 @@ #import "SRGFairPlayAssetResourceLoaderDelegate.h" #import "NSBundle+SRGContentProtection.h" +#import "SRGContentProtectionConstants.h" #import "SRGContentProtectionError.h" +#import #import static BOOL SRGIsFairPlayURL(NSURL *URL) @@ -60,6 +62,14 @@ - (instancetype)init return [self initWithCertificateURL:[NSURL new]]; } +#pragma mark Getters and setters + +- (SRGDiagnosticInformation *)diagnosticInformation +{ + NSString *URN = self.userInfo[SRGContentProtectionURNKey]; + return URN ? [[[SRGDiagnosticsService serviceWithName:@"SRGPlaybackMetrics"] reportWithName:URN] informationForKey:@"drmResult"] : nil; +} + #pragma clang diagnostic pop #pragma mark Subclassing hooks @@ -75,6 +85,9 @@ - (BOOL)shouldProcessResourceLoadingRequest:(AVAssetResourceLoadingRequest *)loa return NO; } + SRGDiagnosticInformation *diagnosticInformation = [self diagnosticInformation]; + [diagnosticInformation startTimeMeasurementForKey:@"duration"]; + self.request = [[SRGNetworkRequest alloc] initWithURLRequest:[NSURLRequest requestWithURL:self.certificateURL] session:self.session options:0 completionBlock:^(NSData * _Nullable certificateData, NSURLResponse * _Nullable response, NSError * _Nullable error) { // Resource loader methods must be called on the main thread if (error) { @@ -125,6 +138,14 @@ - (void)finishLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest wit NSError *friendlyError = [NSError errorWithDomain:SRGContentProtectionErrorDomain code:SRGContentProtectionErrorUnauthorized userInfo:[userInfo copy]]; [loadingRequest finishLoadingWithError:friendlyError]; } + + SRGDiagnosticInformation *diagnosticInformation = [self diagnosticInformation]; + [diagnosticInformation setURL:loadingRequest.request.URL forKey:@"url"]; + + NSHTTPURLResponse *HTTPResponse = [loadingRequest.response isKindOfClass:[NSHTTPURLResponse class]] ? (NSHTTPURLResponse *)loadingRequest.response : nil; + [diagnosticInformation setInteger:HTTPResponse.statusCode forKey:@"httpStatusCode"]; + [diagnosticInformation setString:error.localizedDescription forKey:@"message"]; + [diagnosticInformation stopTimeMeasurementForKey:@"duration"]; } @end diff --git a/Framework/Sources/SRGContentProtection.h b/Framework/Sources/SRGContentProtection.h index aa19bbf..196240b 100644 --- a/Framework/Sources/SRGContentProtection.h +++ b/Framework/Sources/SRGContentProtection.h @@ -12,3 +12,4 @@ FOUNDATION_EXPORT NSString *SRGContentProtectionMarketingVersion(void); // Public headers. #import "AVURLAsset+SRGContentProtection.h" #import "SRGAkamaiToken.h" +#import "SRGContentProtectionConstants.h" diff --git a/Framework/Sources/SRGContentProtectionConstants.h b/Framework/Sources/SRGContentProtectionConstants.h new file mode 100644 index 0000000..b8cb92f --- /dev/null +++ b/Framework/Sources/SRGContentProtectionConstants.h @@ -0,0 +1,12 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import + +/** + * Optional user information keys which can be used to provide more context information when creating an asset. + */ +OBJC_EXPORT NSString * const SRGContentProtectionURNKey; // The URN of the content being played, if any (`NSString`). diff --git a/Framework/Sources/SRGContentProtectionConstants.m b/Framework/Sources/SRGContentProtectionConstants.m new file mode 100644 index 0000000..3fbf984 --- /dev/null +++ b/Framework/Sources/SRGContentProtectionConstants.m @@ -0,0 +1,9 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import "SRGContentProtectionConstants.h" + +NSString * const SRGContentProtectionURNKey = @"SRGContentProtectionURN"; diff --git a/SRGContentProtection.xcodeproj/project.pbxproj b/SRGContentProtection.xcodeproj/project.pbxproj index 6e6dddd..4c68801 100644 --- a/SRGContentProtection.xcodeproj/project.pbxproj +++ b/SRGContentProtection.xcodeproj/project.pbxproj @@ -39,6 +39,8 @@ 6FBF24342147F4C900E576A2 /* SRGDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; }; 6FBF24352147F4C900E576A2 /* SRGDiagnostics.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6FBF24372147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FBF24362147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m */; }; + 6FBF243A21480DB300E576A2 /* SRGContentProtectionConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FBF243821480DB300E576A2 /* SRGContentProtectionConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6FBF243B21480DB300E576A2 /* SRGContentProtectionConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FBF243921480DB300E576A2 /* SRGContentProtectionConstants.m */; }; 6FD810F420FCB58500F250B9 /* AVURLAsset+SRGContentProtection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FD810F220FCB58500F250B9 /* AVURLAsset+SRGContentProtection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6FD810F520FCB58500F250B9 /* AVURLAsset+SRGContentProtection.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD810F320FCB58500F250B9 /* AVURLAsset+SRGContentProtection.m */; }; 6FD8110120FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FD810FF20FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h */; }; @@ -131,6 +133,8 @@ 6FBCA7402109A9F4004CD02D /* AkamaiTokenTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AkamaiTokenTestCase.m; sourceTree = ""; }; 6FBF24302147F3ED00E576A2 /* SRGDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SRGDiagnostics.framework; path = Carthage/Build/iOS/SRGDiagnostics.framework; sourceTree = ""; }; 6FBF24362147FE2E00E576A2 /* SRGAssetResourceLoaderDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SRGAssetResourceLoaderDelegate.m; sourceTree = ""; }; + 6FBF243821480DB300E576A2 /* SRGContentProtectionConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SRGContentProtectionConstants.h; sourceTree = ""; }; + 6FBF243921480DB300E576A2 /* SRGContentProtectionConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SRGContentProtectionConstants.m; sourceTree = ""; }; 6FCBFEF8210B578B006BC355 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 6FCBFEFA210B57BD006BC355 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 6FCBFEFB210B57BD006BC355 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; @@ -227,6 +231,8 @@ 6F7B78692108A05C001E3BBE /* SRGAkamaiToken.m */, 6F0EB53E20FC7FA9009C02CF /* SRGContentProtection.h */, 6F0EB54220FC7FF4009C02CF /* SRGContentProtection.m */, + 6FBF243821480DB300E576A2 /* SRGContentProtectionConstants.h */, + 6FBF243921480DB300E576A2 /* SRGContentProtectionConstants.m */, 6FDE576420FC9DC700719525 /* SRGContentProtectionError.h */, 6FDE576320FC9DC700719525 /* SRGContentProtectionError.m */, ); @@ -351,6 +357,7 @@ files = ( 6F0EB54020FC7FA9009C02CF /* SRGContentProtection.h in Headers */, 6FD810F420FCB58500F250B9 /* AVURLAsset+SRGContentProtection.h in Headers */, + 6FBF243A21480DB300E576A2 /* SRGContentProtectionConstants.h in Headers */, 6FD8110120FCC22500F250B9 /* SRGAkamaiAssetResourceLoaderDelegate.h in Headers */, 6F8A93D220FDB3D200AA6434 /* SRGFairPlayAssetResourceLoaderDelegate.h in Headers */, 6FDE576620FC9DC700719525 /* SRGContentProtectionError.h in Headers */, @@ -541,6 +548,7 @@ 6FDE576520FC9DC700719525 /* SRGContentProtectionError.m in Sources */, 6F8A93D320FDB3D200AA6434 /* SRGFairPlayAssetResourceLoaderDelegate.m in Sources */, 6FD810F520FCB58500F250B9 /* AVURLAsset+SRGContentProtection.m in Sources */, + 6FBF243B21480DB300E576A2 /* SRGContentProtectionConstants.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From f43b383506cbcd8c4e041883d58fc8ddb59aae30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Fri, 14 Sep 2018 08:50:05 +0200 Subject: [PATCH 06/28] Improve asset optional setup --- .../Categories/AVURLAsset+SRGContentProtection.h | 14 +++++++------- .../Categories/AVURLAsset+SRGContentProtection.m | 10 +++++----- .../SRGAkamaiAssetResourceLoaderDelegate.m | 11 ++++++++--- .../SRGAssetResourceLoaderDelegate.h | 4 +++- .../SRGFairPlayAssetResourceLoaderDelegate.m | 10 ++++++++-- .../Sources/SRGContentProtectionConstants.h | 16 ++++++++++++++-- .../Sources/SRGContentProtectionConstants.m | 3 ++- 7 files changed, 47 insertions(+), 21 deletions(-) diff --git a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h index a818d87..4e53b93 100644 --- a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h +++ b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.h @@ -4,6 +4,8 @@ // License information is available from the LICENSE file. // +#import "SRGContentProtectionConstants.h" + #import NS_ASSUME_NONNULL_BEGIN @@ -21,11 +23,10 @@ NS_ASSUME_NONNULL_BEGIN /** * Create an asset supporting standard SRG SSR content protection. * - * @param URL The URL to be played. - * @param userInfo Dictionary to convey optional context information to the content loader (see keys at the top of this - * file). + * @param URL The URL to be played. + * @param options Asset playback options. */ -+ (instancetype)srg_assetWithURL:(NSURL *)URL userInfo:(nullable NSDictionary *)userInfo; ++ (instancetype)srg_assetWithURL:(NSURL *)URL options:(nullable NSDictionary *)options; /** * Same as `-srg_assetWithURL:userInfo:`, but without user information dictionary. @@ -38,10 +39,9 @@ NS_ASSUME_NONNULL_BEGIN * * @param URL The URL to be played. * @param licenseURL The URL where licenses must be retrieved. - * @param userInfo Dictionary to convey optional context information to the content loader (see keys at the top of this - * file). + * @param options Asset playback options. */ -+ (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(nullable NSURL *)licenseURL userInfo:(nullable NSDictionary *)userInfo; ++ (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(nullable NSURL *)licenseURL options:(nullable NSDictionary *)options; /** * Same as `-srg_assetWithURL:licenseURL:userInfo:`, but without user information dictionary. diff --git a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m index fb72cb0..f3d0c47 100644 --- a/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m +++ b/Framework/Sources/Categories/AVURLAsset+SRGContentProtection.m @@ -29,9 +29,9 @@ + (instancetype)srg_assetWithURL:(NSURL *)URL resourceLoaderDelegate:(SRGAssetRe return asset; } -+ (instancetype)srg_assetWithURL:(NSURL *)URL userInfo:(NSDictionary *)userInfo ++ (instancetype)srg_assetWithURL:(NSURL *)URL options:(NSDictionary *)options { - return [self srg_assetWithURL:URL licenseURL:nil userInfo:userInfo]; + return [self srg_assetWithURL:URL licenseURL:nil options:options]; } + (instancetype)srg_assetWithURL:(NSURL *)URL @@ -39,7 +39,7 @@ + (instancetype)srg_assetWithURL:(NSURL *)URL return [self srg_assetWithURL:URL]; } -+ (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(NSURL *)licenseURL userInfo:(NSDictionary *)userInfo ++ (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(NSURL *)licenseURL options:(NSDictionary *)options { SRGAssetResourceLoaderDelegate *resourceLoaderDelegate = nil; if (licenseURL) { @@ -48,14 +48,14 @@ + (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(NSURL *)licenseURL use else if ([URL.host containsString:@"akamai"] && [URL.path.pathExtension isEqualToString:@"m3u8"]) { resourceLoaderDelegate = [[SRGAkamaiAssetResourceLoaderDelegate alloc] init]; } - resourceLoaderDelegate.userInfo = userInfo; + resourceLoaderDelegate.options = options; return [self srg_assetWithURL:URL resourceLoaderDelegate:resourceLoaderDelegate]; } + (instancetype)srg_assetWithURL:(NSURL *)URL licenseURL:(NSURL *)licenseURL { - return [self srg_assetWithURL:URL licenseURL:licenseURL userInfo:nil]; + return [self srg_assetWithURL:URL licenseURL:licenseURL options:nil]; } @end diff --git a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m index 802f3b4..8c0a1df 100644 --- a/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m +++ b/Framework/Sources/ResourceLoaders/SRGAkamaiAssetResourceLoaderDelegate.m @@ -8,7 +8,6 @@ #import "NSBundle+SRGContentProtection.h" #import "SRGAkamaiToken.h" -#import "SRGContentProtectionConstants.h" #import "SRGContentProtectionError.h" #import @@ -49,8 +48,14 @@ - (instancetype)init - (SRGDiagnosticInformation *)diagnosticInformation { - NSString *URN = self.userInfo[SRGContentProtectionURNKey]; - return URN ? [[[SRGDiagnosticsService serviceWithName:@"SRGPlaybackMetrics"] reportWithName:URN] informationForKey:@"tokenResult"] : nil; + NSString *serviceName = self.options[SRGAssetOptionDiagnosticServiceNameKey]; + NSString *reportName = self.options[SRGAssetOptionDiagnosticReportNameKey]; + if (serviceName && reportName) { + return [[[SRGDiagnosticsService serviceWithName:serviceName] reportWithName:reportName] informationForKey:@"tokenResult"]; + } + else { + return nil; + } } #pragma mark Subclassing hooks diff --git a/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h b/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h index 91780f7..33ab1ce 100644 --- a/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h +++ b/Framework/Sources/ResourceLoaders/SRGAssetResourceLoaderDelegate.h @@ -4,6 +4,8 @@ // License information is available from the LICENSE file. // +#import "SRGContentProtectionConstants.h" + #import NS_ASSUME_NONNULL_BEGIN @@ -34,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Optional information associated with the receiver. */ -@property (nonatomic, nullable) NSDictionary *userInfo; +@property (nonatomic, nullable) NSDictionary *options; @end diff --git a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m index 6efeabd..24ec553 100644 --- a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m +++ b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m @@ -66,8 +66,14 @@ - (instancetype)init - (SRGDiagnosticInformation *)diagnosticInformation { - NSString *URN = self.userInfo[SRGContentProtectionURNKey]; - return URN ? [[[SRGDiagnosticsService serviceWithName:@"SRGPlaybackMetrics"] reportWithName:URN] informationForKey:@"drmResult"] : nil; + NSString *serviceName = self.options[SRGAssetOptionDiagnosticServiceNameKey]; + NSString *reportName = self.options[SRGAssetOptionDiagnosticReportNameKey]; + if (serviceName && reportName) { + return [[[SRGDiagnosticsService serviceWithName:serviceName] reportWithName:reportName] informationForKey:@"drmResult"]; + } + else { + return nil; + } } #pragma clang diagnostic pop diff --git a/Framework/Sources/SRGContentProtectionConstants.h b/Framework/Sources/SRGContentProtectionConstants.h index b8cb92f..d7342ee 100644 --- a/Framework/Sources/SRGContentProtectionConstants.h +++ b/Framework/Sources/SRGContentProtectionConstants.h @@ -7,6 +7,18 @@ #import /** - * Optional user information keys which can be used to provide more context information when creating an asset. + * Options for asset playback. */ -OBJC_EXPORT NSString * const SRGContentProtectionURNKey; // The URN of the content being played, if any (`NSString`). +typedef NSString * SRGAssetOption NS_TYPED_ENUM; + +/** + * The diagnostics service which internal information should be sent to. If omitted, no diagnostic information will be + * generated. + */ +OBJC_EXPORT NSString * const SRGAssetOptionDiagnosticServiceNameKey; + +/** + * The name of the diagnostic report to associate information with. If omitted, no diagnostic information will be + * generated. + */ +OBJC_EXPORT NSString * const SRGAssetOptionDiagnosticReportNameKey; diff --git a/Framework/Sources/SRGContentProtectionConstants.m b/Framework/Sources/SRGContentProtectionConstants.m index 3fbf984..1aa85c1 100644 --- a/Framework/Sources/SRGContentProtectionConstants.m +++ b/Framework/Sources/SRGContentProtectionConstants.m @@ -6,4 +6,5 @@ #import "SRGContentProtectionConstants.h" -NSString * const SRGContentProtectionURNKey = @"SRGContentProtectionURN"; +NSString * const SRGAssetOptionDiagnosticServiceNameKey = @"SRGAssetOptionDiagnosticServiceName"; +NSString * const SRGAssetOptionDiagnosticReportNameKey = @"SRGAssetOptionDiagnosticReportName"; From 6f471fee8d02de319a808f74a44342df3195145e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Mon, 17 Sep 2018 13:24:39 +0200 Subject: [PATCH 07/28] Add public flag --- Framework/Sources/SRGContentProtection.h | 3 +++ Framework/Sources/SRGContentProtection.m | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/Framework/Sources/SRGContentProtection.h b/Framework/Sources/SRGContentProtection.h index 196240b..09fcba0 100644 --- a/Framework/Sources/SRGContentProtection.h +++ b/Framework/Sources/SRGContentProtection.h @@ -9,6 +9,9 @@ // Official version number. FOUNDATION_EXPORT NSString *SRGContentProtectionMarketingVersion(void); +// Return `YES` iff run in a public (open source) setup. Always `NO`. +FOUNDATION_EXPORT BOOL SRGContentProtectionIsPublic(void); + // Public headers. #import "AVURLAsset+SRGContentProtection.h" #import "SRGAkamaiToken.h" diff --git a/Framework/Sources/SRGContentProtection.m b/Framework/Sources/SRGContentProtection.m index 8ccd977..f44b44e 100644 --- a/Framework/Sources/SRGContentProtection.m +++ b/Framework/Sources/SRGContentProtection.m @@ -12,3 +12,8 @@ { return [NSBundle srg_contentProtectionBundle].infoDictionary[@"CFBundleShortVersionString"]; } + +BOOL SRGContentProtectionIsPublic(void) +{ + return NO; +} From 08cca13c711e502c367f4b36989426aaa7caae9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Mon, 17 Sep 2018 15:56:12 +0200 Subject: [PATCH 08/28] Replace function with category method on NSBundle Can be easily checked even if the framework is missing. --- Framework/Sources/SRGContentProtection.h | 12 +++++++++--- Framework/Sources/SRGContentProtection.m | 6 +++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Framework/Sources/SRGContentProtection.h b/Framework/Sources/SRGContentProtection.h index 09fcba0..564969a 100644 --- a/Framework/Sources/SRGContentProtection.h +++ b/Framework/Sources/SRGContentProtection.h @@ -9,10 +9,16 @@ // Official version number. FOUNDATION_EXPORT NSString *SRGContentProtectionMarketingVersion(void); -// Return `YES` iff run in a public (open source) setup. Always `NO`. -FOUNDATION_EXPORT BOOL SRGContentProtectionIsPublic(void); - // Public headers. #import "AVURLAsset+SRGContentProtection.h" #import "SRGAkamaiToken.h" #import "SRGContentProtectionConstants.h" + +@interface NSBundle (SRGContentProtectionVersion) + +/** + * Return `YES` iff run in a public (open source) setup. Always `NO`. + */ ++ (BOOL)srg_contentProtectionIsPublic; + +@end diff --git a/Framework/Sources/SRGContentProtection.m b/Framework/Sources/SRGContentProtection.m index f44b44e..94efc85 100644 --- a/Framework/Sources/SRGContentProtection.m +++ b/Framework/Sources/SRGContentProtection.m @@ -13,7 +13,11 @@ return [NSBundle srg_contentProtectionBundle].infoDictionary[@"CFBundleShortVersionString"]; } -BOOL SRGContentProtectionIsPublic(void) +@implementation NSBundle (SRGContentProtectionVersion) + ++ (BOOL)srg_contentProtectionIsPublic { return NO; } + +@end From 060bf99ba2d63ca20cb4ff52112330f6a6703378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Tue, 18 Sep 2018 08:45:11 +0200 Subject: [PATCH 09/28] Revert "Replace function with category method on NSBundle" This reverts commit 92fcdeed91df16cde60da127710d9a4b44168093. --- Framework/Sources/SRGContentProtection.h | 12 +++--------- Framework/Sources/SRGContentProtection.m | 6 +----- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Framework/Sources/SRGContentProtection.h b/Framework/Sources/SRGContentProtection.h index 564969a..09fcba0 100644 --- a/Framework/Sources/SRGContentProtection.h +++ b/Framework/Sources/SRGContentProtection.h @@ -9,16 +9,10 @@ // Official version number. FOUNDATION_EXPORT NSString *SRGContentProtectionMarketingVersion(void); +// Return `YES` iff run in a public (open source) setup. Always `NO`. +FOUNDATION_EXPORT BOOL SRGContentProtectionIsPublic(void); + // Public headers. #import "AVURLAsset+SRGContentProtection.h" #import "SRGAkamaiToken.h" #import "SRGContentProtectionConstants.h" - -@interface NSBundle (SRGContentProtectionVersion) - -/** - * Return `YES` iff run in a public (open source) setup. Always `NO`. - */ -+ (BOOL)srg_contentProtectionIsPublic; - -@end diff --git a/Framework/Sources/SRGContentProtection.m b/Framework/Sources/SRGContentProtection.m index 94efc85..f44b44e 100644 --- a/Framework/Sources/SRGContentProtection.m +++ b/Framework/Sources/SRGContentProtection.m @@ -13,11 +13,7 @@ return [NSBundle srg_contentProtectionBundle].infoDictionary[@"CFBundleShortVersionString"]; } -@implementation NSBundle (SRGContentProtectionVersion) - -+ (BOOL)srg_contentProtectionIsPublic +BOOL SRGContentProtectionIsPublic(void) { return NO; } - -@end From 8938dd3cef947c379de2b4b0a588d517fc9f1cc4 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Wed, 19 Sep 2018 16:48:20 +0200 Subject: [PATCH 10/28] Update dependencies --- Cartfile | 2 +- Cartfile.resolved | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cartfile b/Cartfile index 7429943..aedf76b 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ -github "SRGSSR/srgdiagnostics-ios" "793ded847636b8c87d79542daf8765f50e567559" +github "SRGSSR/srgdiagnostics-ios" "ca1f4130bea4358490961c8a818ee9649d32298a" github "SRGSSR/srgnetwork-ios" "0.2" \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index 7429943..3ed05eb 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,2 @@ -github "SRGSSR/srgdiagnostics-ios" "793ded847636b8c87d79542daf8765f50e567559" -github "SRGSSR/srgnetwork-ios" "0.2" \ No newline at end of file +github "SRGSSR/srgdiagnostics-ios" "ca1f4130bea4358490961c8a818ee9649d32298a" +github "SRGSSR/srgnetwork-ios" "0.2" From 207dcacb3be8fef2edc899f9fff493becc591ec3 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Thu, 20 Sep 2018 10:23:56 +0200 Subject: [PATCH 11/28] Update dependencies --- Cartfile | 2 +- Cartfile.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cartfile b/Cartfile index aedf76b..202cc0b 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ -github "SRGSSR/srgdiagnostics-ios" "ca1f4130bea4358490961c8a818ee9649d32298a" +github "SRGSSR/srgdiagnostics-ios" "17e32379a13b5e5435233cd83a609a3f2d9b5317" github "SRGSSR/srgnetwork-ios" "0.2" \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index 3ed05eb..6bb8cde 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,2 @@ -github "SRGSSR/srgdiagnostics-ios" "ca1f4130bea4358490961c8a818ee9649d32298a" +github "SRGSSR/srgdiagnostics-ios" "17e32379a13b5e5435233cd83a609a3f2d9b5317" github "SRGSSR/srgnetwork-ios" "0.2" From 2daeb75e6b33440807d2b55dfee4041de3e79e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Thu, 20 Sep 2018 13:53:42 +0200 Subject: [PATCH 12/28] Update to class properties --- Demo/Sources/Application/main.m | 2 +- Framework/Sources/Categories/NSBundle+SRGContentProtection.h | 4 ++-- Framework/Sources/Categories/NSBundle+SRGContentProtection.m | 2 +- .../ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m | 2 +- Framework/Sources/SRGAkamaiToken.m | 2 +- Framework/Sources/SRGContentProtection.m | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Demo/Sources/Application/main.m b/Demo/Sources/Application/main.m index 6e3f7a3..2c2a00b 100644 --- a/Demo/Sources/Application/main.m +++ b/Demo/Sources/Application/main.m @@ -11,6 +11,6 @@ int main(int argc, char *argv[]) { @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + return UIApplicationMain(argc, argv, nil, NSStringFromClass(AppDelegate.class)); } } diff --git a/Framework/Sources/Categories/NSBundle+SRGContentProtection.h b/Framework/Sources/Categories/NSBundle+SRGContentProtection.h index f0ce67a..95b5000 100644 --- a/Framework/Sources/Categories/NSBundle+SRGContentProtection.h +++ b/Framework/Sources/Categories/NSBundle+SRGContentProtection.h @@ -11,14 +11,14 @@ NS_ASSUME_NONNULL_BEGIN /** * Convenience macro for localized strings associated with the framework. */ -#define SRGContentProtectionLocalizedString(key, comment) [[NSBundle srg_contentProtectionBundle] localizedStringForKey:(key) value:@"" table:nil] +#define SRGContentProtectionLocalizedString(key, comment) [NSBundle.srg_contentProtectionBundle localizedStringForKey:(key) value:@"" table:nil] @interface NSBundle (SRGContentProtection) /** * The framework resource bundle. */ -+ (NSBundle *)srg_contentProtectionBundle; +@property (class, nonatomic, readonly) NSBundle *srg_contentProtectionBundle; @end diff --git a/Framework/Sources/Categories/NSBundle+SRGContentProtection.m b/Framework/Sources/Categories/NSBundle+SRGContentProtection.m index f4c8b7b..aca394f 100644 --- a/Framework/Sources/Categories/NSBundle+SRGContentProtection.m +++ b/Framework/Sources/Categories/NSBundle+SRGContentProtection.m @@ -17,7 +17,7 @@ + (instancetype)srg_contentProtectionBundle static NSBundle *s_bundle; static dispatch_once_t s_onceToken; dispatch_once(&s_onceToken, ^{ - NSString *bundlePath = [[NSBundle bundleForClass:[SRGAkamaiAssetResourceLoaderDelegate class]].bundlePath stringByAppendingPathComponent:@"SRGContentProtection.bundle"]; + NSString *bundlePath = [[NSBundle bundleForClass:SRGAkamaiAssetResourceLoaderDelegate.class].bundlePath stringByAppendingPathComponent:@"SRGContentProtection.bundle"]; s_bundle = [NSBundle bundleWithPath:bundlePath]; NSAssert(s_bundle, @"Please add SRGContentProtection.bundle to your project resources"); }); diff --git a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m index 24ec553..807e93d 100644 --- a/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m +++ b/Framework/Sources/ResourceLoaders/SRGFairPlayAssetResourceLoaderDelegate.m @@ -148,7 +148,7 @@ - (void)finishLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest wit SRGDiagnosticInformation *diagnosticInformation = [self diagnosticInformation]; [diagnosticInformation setURL:loadingRequest.request.URL forKey:@"url"]; - NSHTTPURLResponse *HTTPResponse = [loadingRequest.response isKindOfClass:[NSHTTPURLResponse class]] ? (NSHTTPURLResponse *)loadingRequest.response : nil; + NSHTTPURLResponse *HTTPResponse = [loadingRequest.response isKindOfClass:NSHTTPURLResponse.class] ? (NSHTTPURLResponse *)loadingRequest.response : nil; [diagnosticInformation setInteger:HTTPResponse.statusCode forKey:@"httpStatusCode"]; [diagnosticInformation setString:error.localizedDescription forKey:@"message"]; [diagnosticInformation stopTimeMeasurementForKey:@"duration"]; diff --git a/Framework/Sources/SRGAkamaiToken.m b/Framework/Sources/SRGAkamaiToken.m index c690d54..92543d9 100644 --- a/Framework/Sources/SRGAkamaiToken.m +++ b/Framework/Sources/SRGAkamaiToken.m @@ -32,7 +32,7 @@ + (SRGNetworkRequest *)tokenizeURL:(NSURL *)URL withSession:(NSURLSession *)sess NSString *token = nil; id tokenDictionary = JSONDictionary[@"token"]; - if ([tokenDictionary isKindOfClass:[NSDictionary class]]) { + if ([tokenDictionary isKindOfClass:NSDictionary.class]) { token = [tokenDictionary objectForKey:@"authparams"]; } diff --git a/Framework/Sources/SRGContentProtection.m b/Framework/Sources/SRGContentProtection.m index f44b44e..5af2d90 100644 --- a/Framework/Sources/SRGContentProtection.m +++ b/Framework/Sources/SRGContentProtection.m @@ -10,7 +10,7 @@ NSString *SRGContentProtectionMarketingVersion(void) { - return [NSBundle srg_contentProtectionBundle].infoDictionary[@"CFBundleShortVersionString"]; + return NSBundle.srg_contentProtectionBundle.infoDictionary[@"CFBundleShortVersionString"]; } BOOL SRGContentProtectionIsPublic(void) From c8304398326d440454ff5d0acab4a9116f21b2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Thu, 20 Sep 2018 13:54:18 +0200 Subject: [PATCH 13/28] Modernize settings with Xcode 10 --- SRGContentProtection.xcodeproj/project.pbxproj | 6 +++++- .../xcshareddata/xcschemes/SRGContentProtection.xcscheme | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/SRGContentProtection.xcodeproj/project.pbxproj b/SRGContentProtection.xcodeproj/project.pbxproj index 4c68801..aeca431 100644 --- a/SRGContentProtection.xcodeproj/project.pbxproj +++ b/SRGContentProtection.xcodeproj/project.pbxproj @@ -450,7 +450,7 @@ 6F0EB52820FC7F58009C02CF /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0940; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = "SRG SSR"; TargetAttributes = { 6F0C98E52121E1C200073AB6 = { @@ -612,6 +612,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -744,6 +745,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -926,6 +928,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -989,6 +992,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; diff --git a/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme b/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme index f5e379a..8692969 100644 --- a/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme +++ b/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme @@ -1,6 +1,6 @@ Date: Thu, 20 Sep 2018 13:54:50 +0200 Subject: [PATCH 14/28] Parallelize and randomize tests --- .../xcshareddata/xcschemes/SRGContentProtection.xcscheme | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme b/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme index 8692969..4ca64e6 100644 --- a/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme +++ b/SRGContentProtection.xcodeproj/xcshareddata/xcschemes/SRGContentProtection.xcscheme @@ -30,7 +30,9 @@ shouldUseLaunchSchemeArgsEnv = "YES"> + skipped = "NO" + parallelizable = "YES" + testExecutionOrdering = "random"> Date: Thu, 20 Sep 2018 13:55:56 +0200 Subject: [PATCH 15/28] Update documentation --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 732e0b7..fa5f2c2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,7 @@ The SRG Content Protection framework contains the sensitive logic required for p ## Compatibility -The library is suitable for applications running on iOS 9 and above. The project is meant to be opened with the latest Xcode version (currently Xcode 9). +The library is suitable for applications running on iOS 9 and above. The project is meant to be opened with the latest Xcode version (currently Xcode 10). ## Installation From 3551d397ac8fa90d2b83a4c8528e30089cf1278b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20De=CC=81fago?= Date: Thu, 20 Sep 2018 13:57:35 +0200 Subject: [PATCH 16/28] Fix section name --- .../Demos/DemosViewController.storyboard | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Demo/Sources/Demos/DemosViewController.storyboard b/Demo/Sources/Demos/DemosViewController.storyboard index e845c6c..ced0f67 100644 --- a/Demo/Sources/Demos/DemosViewController.storyboard +++ b/Demo/Sources/Demos/DemosViewController.storyboard @@ -1,11 +1,11 @@ - + - + @@ -28,7 +28,7 @@