diff --git a/.gitignore b/.gitignore index f3776ecc..3882e93a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ xcuserdata/ *.xcscmblueprint xcuserdata -/fastlane/*.xcresult +/fastlane/xcresult /fastlane/*.xml /vendor diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..ec08ab70 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,35 @@ +inherit_mode: + merge: + - Include + +AllCops: + Exclude: + - 'Carthage/**/*' + - 'Demo/Carthage/**/*' + - 'vendor/**/*' + Include: + - 'fastlane/Pluginfile' + +# this would cause errors with long lanes +Metrics/BlockLength: + Enabled: true + ExcludedMethods: ['platform', 'for_platform'] + +# Lane description and gem lines can be long +Layout/LineLength: + Enabled: true + Max: 100 + IgnoredPatterns: ['^gem', '^(\s+|)desc', '^(\s+|)UI.'] + +# They have not to be snake_case +Naming/FileName: + Exclude: + - '**/Appfile' + - '**/Gemfile' + - '**/Pluginfile' + - '**/Fastfile' + +# Variables have to be as described in fastlane documentation +Style/RedundantInterpolation: + Exclude: + - '**/Appfile' diff --git a/Demo/Demo.xcconfig b/Demo/Demo.xcconfig index 3a5dad24..bb45cbcb 100644 --- a/Demo/Demo.xcconfig +++ b/Demo/Demo.xcconfig @@ -1,5 +1,5 @@ // Version information -MARKETING_VERSION = 6.1.1 +MARKETING_VERSION = 7.0.0 // Deployment targets IPHONEOS_DEPLOYMENT_TARGET = 9.0 diff --git a/Demo/SRGAnalytics-demo.xcodeproj/project.pbxproj b/Demo/SRGAnalytics-demo.xcodeproj/project.pbxproj index b635e107..75788d4f 100644 --- a/Demo/SRGAnalytics-demo.xcodeproj/project.pbxproj +++ b/Demo/SRGAnalytics-demo.xcodeproj/project.pbxproj @@ -185,7 +185,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = SRG; - LastUpgradeCheck = 1220; + LastUpgradeCheck = 1240; ORGANIZATIONNAME = "SRG SSR"; TargetAttributes = { E6FC7E871D61F95C00A55085 = { diff --git a/Demo/SRGAnalytics-demo.xcodeproj/xcshareddata/xcschemes/SRGAnalytics-demo.xcscheme b/Demo/SRGAnalytics-demo.xcodeproj/xcshareddata/xcschemes/SRGAnalytics-demo.xcscheme index c2cdba36..5b811b3d 100644 --- a/Demo/SRGAnalytics-demo.xcodeproj/xcshareddata/xcschemes/SRGAnalytics-demo.xcscheme +++ b/Demo/SRGAnalytics-demo.xcodeproj/xcshareddata/xcschemes/SRGAnalytics-demo.xcscheme @@ -1,6 +1,6 @@ = 0.7.0) - trainer (0.9.1.1) - fastlane (>= 2.25.0) - plist (>= 3.1.0, < 4.0.0) - GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.2) + CFPropertyList (3.0.3) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) + artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.298.0) - aws-sdk-core (3.94.0) + aws-partitions (1.422.0) + aws-sdk-core (3.111.2) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.30.0) - aws-sdk-core (~> 3, >= 3.71.0) + aws-sdk-kms (1.41.0) + aws-sdk-core (~> 3, >= 3.109.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.61.2) - aws-sdk-core (~> 3, >= 3.83.0) + aws-sdk-s3 (1.87.0) + aws-sdk-core (~> 3, >= 3.109.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.2) - aws-eventstream (~> 1.0, >= 1.0.2) - babosa (1.0.3) + aws-sigv4 (1.2.2) + aws-eventstream (~> 1, >= 1.0.2) + babosa (1.0.4) claide (1.0.3) colored (1.2) colored2 (3.1.2) commander-fastlane (4.4.6) highline (~> 1.7.2) - declarative (0.0.10) + declarative (0.0.20) declarative-option (0.1.0) - digest-crc (0.5.1) + digest-crc (0.6.3) + rake (>= 12.0.0, < 14.0.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.5) - emoji_regex (1.0.1) - excon (0.73.0) - faraday (0.17.3) + dotenv (2.7.6) + emoji_regex (3.2.1) + excon (0.78.1) + faraday (1.3.0) + faraday-net_http (~> 1.0) multipart-post (>= 1.2, < 3) - faraday-cookie_jar (0.0.6) - faraday (>= 0.7.4) + ruby2_keywords + faraday-cookie_jar (0.0.7) + faraday (>= 0.8.0) http-cookie (~> 1.0.0) - faraday_middleware (0.13.1) - faraday (>= 0.7.4, < 1.0) - fastimage (2.1.7) - fastlane (2.145.0) + faraday-net_http (1.0.1) + faraday_middleware (1.0.0) + faraday (~> 1.0) + fastimage (2.2.1) + fastlane (2.172.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) + artifactory (~> 3.0) aws-sdk-s3 (~> 1.0) - babosa (>= 1.0.2, < 2.0.0) + babosa (>= 1.0.3, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) colored commander-fastlane (>= 4.4.6, < 5.0.0) dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 2.0) + emoji_regex (>= 0.1, < 4.0) excon (>= 0.71.0, < 1.0.0) - faraday (~> 0.17) + faraday (~> 1.0) faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 0.13.1) + faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) - google-api-client (>= 0.29.2, < 0.37.0) + google-api-client (>= 0.37.0, < 0.39.0) google-cloud-storage (>= 1.15.0, < 2.0.0) highline (>= 1.7.2, < 2.0.0) json (< 3.0.0) - jwt (~> 2.1.0) + jwt (>= 2.1.0, < 3) mini_magick (>= 4.9.4, < 5.0.0) - multi_xml (~> 0.5) multipart-post (~> 2.0.0) plist (>= 3.1.0, < 4.0.0) - public_suffix (~> 2.0.0) - rubyzip (>= 1.3.0, < 2.0.0) + rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) simctl (~> 1.6.3) slack-notifier (>= 2.0.0, < 3.0.0) @@ -92,9 +85,10 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) - fastlane-plugin-xcconfig (2.0.0) + fastlane-plugin-trainer (0.4.1) + trainer (>= 0.7.0) gh_inspector (1.1.3) - google-api-client (0.36.4) + google-api-client (0.38.0) addressable (~> 2.5, >= 2.5.1) googleauth (~> 0.9) httpclient (>= 2.8.1, < 3.0) @@ -102,20 +96,35 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.0) signet (~> 0.12) + google-apis-core (0.2.1) + addressable (~> 2.5, >= 2.5.1) + googleauth (~> 0.14) + httpclient (>= 2.8.1, < 3.0) + mini_mime (~> 1.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.0) + rexml + signet (~> 0.14) + webrick + google-apis-iamcredentials_v1 (0.1.0) + google-apis-core (~> 0.1) + google-apis-storage_v1 (0.1.0) + google-apis-core (~> 0.1) google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.3.1) + google-cloud-env (1.4.0) faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.0.0) - google-cloud-storage (1.26.0) + google-cloud-errors (1.0.1) + google-cloud-storage (1.30.0) addressable (~> 2.5) digest-crc (~> 0.4) - google-api-client (~> 0.33) + google-apis-iamcredentials_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.1) google-cloud-core (~> 1.2) googleauth (~> 0.9) mini_mime (~> 1.0) - googleauth (0.12.0) + googleauth (0.15.0) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -127,28 +136,30 @@ GEM domain_name (~> 0.5) httpclient (2.8.3) jmespath (1.4.0) - json (2.3.0) - jwt (2.1.0) + json (2.5.1) + jwt (2.2.2) memoist (0.16.2) - mini_magick (4.10.1) + mini_magick (4.11.0) mini_mime (1.0.2) - multi_json (1.14.1) - multi_xml (0.6.0) + multi_json (1.15.0) multipart-post (2.0.0) - nanaimo (0.2.6) - naturally (2.2.0) - os (1.1.0) - plist (3.5.0) - public_suffix (2.0.5) + nanaimo (0.3.0) + naturally (2.2.1) + os (1.1.1) + plist (3.6.0) + public_suffix (4.0.6) + rake (13.0.3) representable (3.0.4) declarative (< 0.1.0) declarative-option (< 0.2.0) uber (< 0.2.0) retriable (3.1.2) + rexml (3.2.4) rouge (2.0.7) - rubyzip (1.3.0) + ruby2_keywords (0.0.4) + rubyzip (2.3.0) security (0.1.3) - signet (0.14.0) + signet (0.14.1) addressable (~> 2.3) faraday (>= 0.17.3, < 2.0) jwt (>= 1.5, < 3.0) @@ -160,8 +171,11 @@ GEM terminal-notifier (2.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) + trainer (0.9.1) + fastlane (>= 2.25.0) + plist (>= 3.1.0, < 4.0.0) tty-cursor (0.7.1) - tty-screen (0.7.1) + tty-screen (0.8.1) tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) @@ -169,16 +183,20 @@ GEM unf_ext unf_ext (0.0.7.7) unicode-display_width (1.7.0) + webrick (1.7.0) word_wrap (1.0.0) - xcodeproj (1.16.0) + xcode-install (2.6.6) + claide (>= 0.9.1, < 1.1.0) + fastlane (>= 2.1.0, < 3.0.0) + xcodeproj (1.19.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.2.6) + nanaimo (~> 0.3.0) xcpretty (0.3.0) rouge (~> 2.0.7) - xcpretty-travis-formatter (1.0.0) + xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) PLATFORMS @@ -186,8 +204,8 @@ PLATFORMS DEPENDENCIES fastlane - fastlane-plugin-trainer! - fastlane-plugin-xcconfig + fastlane-plugin-trainer + xcode-install BUNDLED WITH 1.17.2 diff --git a/Package.resolved b/Package.resolved index 75900dff..2815aeaf 100644 --- a/Package.resolved +++ b/Package.resolved @@ -3,11 +3,11 @@ "pins": [ { "package": "ComScore", - "repositoryURL": "https://github.com/SRGSSR/ComScore-xcframework-apple.git", + "repositoryURL": "https://github.com/comScore/Comscore-Swift-Package-Manager.git", "state": { "branch": null, - "revision": "b5dc5dc60435f363a744e17975957361c844aa38", - "version": "6.6.0" + "revision": "805ef197755a66e634fccb5d23d9068ca5c1f395", + "version": "6.7.0" } }, { @@ -51,8 +51,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgappearance-apple.git", "state": { "branch": null, - "revision": "80ebf882d46451001c1fd7d3e21baa264ad88477", - "version": "3.0.1" + "revision": "1e635509b57626073cfff3d74037214e2e42e6e5", + "version": "3.0.2" } }, { @@ -60,17 +60,17 @@ "repositoryURL": "https://github.com/SRGSSR/srgcontentprotection-apple.git", "state": { "branch": null, - "revision": "596f4161b4460fc648d30d5d3ca2c16f249863ef", - "version": "3.0.1" + "revision": "a839c5343c8789f33c34d07d2a24a7de6eb4c054", + "version": "3.0.3" } }, { "package": "SRGDataProvider", "repositoryURL": "https://github.com/SRGSSR/srgdataprovider-apple.git", "state": { - "branch": null, - "revision": "02673482b77adacbcdeac82db60116f893d2d817", - "version": "9.1.0" + "branch": "develop", + "revision": "fae257b900f89242eff367258ec3e546848a1dee", + "version": null } }, { @@ -78,17 +78,17 @@ "repositoryURL": "https://github.com/SRGSSR/srgdiagnostics-apple.git", "state": { "branch": null, - "revision": "5d2ef5c833a5cf6e56762a9c506e73f58ccad5e8", - "version": "3.0.0" + "revision": "ca2fe9329aa174281ac97bd4630096ff7cf41d58", + "version": "3.0.1" } }, { "package": "SRGIdentity", "repositoryURL": "https://github.com/SRGSSR/srgidentity-apple.git", "state": { - "branch": null, - "revision": "e1fe679ea1aefb5b4c80445ae70aa86b9a497aea", - "version": "3.0.0" + "branch": "develop", + "revision": "20fd3c6e0975c97e8df51e817791e210a15784c1", + "version": null } }, { @@ -96,8 +96,8 @@ "repositoryURL": "https://github.com/SRGSSR/srglogger-apple.git", "state": { "branch": null, - "revision": "cfc39d1223ed039aeb7df38c6c7570977b22d1aa", - "version": "3.0.0" + "revision": "9e5bf082222f5499996b931a8651aac6ea17ba4a", + "version": "3.0.1" } }, { @@ -105,8 +105,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgmediaplayer-apple.git", "state": { "branch": null, - "revision": "a0f192296817d471fbe48dc8623ab851a9266369", - "version": "6.1.0" + "revision": "7ba6b8f78205ec9186d67aa9d1c40e376ffd4909", + "version": "6.1.2" } }, { @@ -114,8 +114,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgnetwork-apple.git", "state": { "branch": null, - "revision": "734fe399088b2f846e9e69d48a43118f6a8dc0d2", - "version": "3.0.0" + "revision": "76a83f3b6219f501b589317f8cc0a11556e0565a", + "version": "3.0.1" } }, { diff --git a/Package.swift b/Package.swift index ae49f212..74aff314 100644 --- a/Package.swift +++ b/Package.swift @@ -3,7 +3,7 @@ import PackageDescription struct ProjectSettings { - static let marketingVersion: String = "6.1.1" + static let marketingVersion: String = "7.0.0" } let package = Package( @@ -36,10 +36,10 @@ let package = Package( ) ], dependencies: [ - .package(name: "ComScore", url: "https://github.com/SRGSSR/ComScore-xcframework-apple.git", .upToNextMinor(from: "6.6.0")), + .package(name: "ComScore", url: "https://github.com/comScore/Comscore-Swift-Package-Manager.git", .upToNextMinor(from: "6.7.0")), .package(name: "SRGContentProtection", url: "https://github.com/SRGSSR/srgcontentprotection-apple.git", .upToNextMinor(from: "3.0.1")), - .package(name: "SRGDataProvider", url: "https://github.com/SRGSSR/srgdataprovider-apple.git", .upToNextMinor(from: "9.1.0")), - .package(name: "SRGIdentity", url: "https://github.com/SRGSSR/srgidentity-apple.git", .upToNextMinor(from: "3.0.0")), + .package(name: "SRGDataProvider", url: "https://github.com/SRGSSR/srgdataprovider-apple.git", .upToNextMinor(from: "10.0.0")), + .package(name: "SRGIdentity", url: "https://github.com/SRGSSR/srgidentity-apple.git", .upToNextMinor(from: "3.0.3")), .package(name: "SRGLogger", url: "https://github.com/SRGSSR/srglogger-apple.git", .upToNextMinor(from: "3.0.0")), .package(name: "SRGMediaPlayer", url: "https://github.com/SRGSSR/srgmediaplayer-apple.git", .upToNextMinor(from: "6.1.0")), .package(name: "TCCore", url: "https://github.com/SRGSSR/TCCore-xcframework-apple.git", .exact("4.5.4-srg3")), diff --git a/Sources/SRGAnalytics/NSString+SRGAnalytics.m b/Sources/SRGAnalytics/NSString+SRGAnalytics.m index 43c7dead..bf3cb851 100644 --- a/Sources/SRGAnalytics/NSString+SRGAnalytics.m +++ b/Sources/SRGAnalytics/NSString+SRGAnalytics.m @@ -14,7 +14,7 @@ - (NSString *)srg_comScoreFormattedString NSLocale *posixLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; NSString *normalizedString = [self.lowercaseString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:posixLocale]; - // See rules at https://srfmmz.atlassian.net/wiki/display/SRGPLAY/Measurement+of+SRG+Player+Apps + // See rules at https://confluence.srg.beecollaboration.com/display/SRGPLAY/Measurement+of+SRG+Player+Apps#MeasurementofSRGPlayerApps-SupportedCharacters NSCharacterSet *andSet = [NSCharacterSet characterSetWithCharactersInString:@"+&"]; normalizedString = [[normalizedString componentsSeparatedByCharactersInSet:andSet] componentsJoinedByString:@"and"]; diff --git a/Sources/SRGAnalytics/SRGAnalyticsConfiguration.m b/Sources/SRGAnalytics/SRGAnalyticsConfiguration.m index 4e346528..bfa09607 100644 --- a/Sources/SRGAnalytics/SRGAnalyticsConfiguration.m +++ b/Sources/SRGAnalytics/SRGAnalyticsConfiguration.m @@ -23,7 +23,6 @@ @interface SRGAnalyticsConfiguration () @property (nonatomic, copy) SRGAnalyticsBusinessUnitIdentifier businessUnitIdentifier; @property (nonatomic) NSInteger container; @property (nonatomic, copy) NSString *siteName; -@property (nonatomic, copy) NSString *netMetrixIdentifier; @end @@ -34,13 +33,11 @@ @implementation SRGAnalyticsConfiguration - (instancetype)initWithBusinessUnitIdentifier:(SRGAnalyticsBusinessUnitIdentifier)businessUnitIdentifier container:(NSInteger)container siteName:(NSString *)siteName - netMetrixIdentifier:(NSString *)netMetrixIdentifier { if (self = [super init] ) { self.businessUnitIdentifier = businessUnitIdentifier; self.container = container; self.siteName = siteName; - self.netMetrixIdentifier = netMetrixIdentifier; self.centralized = YES; self.environmentMode = SRGAnalyticsEnvironmentModeAutomatic; } @@ -66,21 +63,6 @@ - (NSInteger)site return s_sites[businessUnitIdentifier].integerValue; } -- (NSString *)netMetrixDomain -{ - // HTTPs domains as documented here: https://srfmmz.atlassian.net/wiki/display/SRGPLAY/HTTPS+Transition - static dispatch_once_t s_onceToken; - static NSDictionary *s_domains; - dispatch_once(&s_onceToken, ^{ - s_domains = @{ SRGAnalyticsBusinessUnitIdentifierRSI : @"rsi-ssl", - SRGAnalyticsBusinessUnitIdentifierRTR : @"rtr-ssl", - SRGAnalyticsBusinessUnitIdentifierRTS : @"rts-ssl", - SRGAnalyticsBusinessUnitIdentifierSRF : @"sftv-ssl", - SRGAnalyticsBusinessUnitIdentifierSWI : @"sinf-ssl" }; - }); - return s_domains[self.businessUnitIdentifier]; -} - - (SRGAnalyticsEnvironment)environment { switch (self.environmentMode) { @@ -110,7 +92,6 @@ - (id)copyWithZone:(NSZone *)zone configuration.businessUnitIdentifier = self.businessUnitIdentifier; configuration.container = self.container; configuration.siteName = self.siteName; - configuration.netMetrixIdentifier = self.netMetrixIdentifier; configuration.centralized = self.centralized; configuration.environmentMode = self.environmentMode; configuration.unitTesting = self.unitTesting; @@ -121,14 +102,13 @@ - (id)copyWithZone:(NSZone *)zone - (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p; businessUnitIdentifier = %@; site = %@; container = %@; siteName = %@; netMetrixIdentifier = %@>", + return [NSString stringWithFormat:@"<%@: %p; businessUnitIdentifier = %@; site = %@; container = %@; siteName = %@", self.class, self, self.businessUnitIdentifier, @(self.site), @(self.container), - self.siteName, - self.netMetrixIdentifier]; + self.siteName]; } @end diff --git a/Sources/SRGAnalytics/SRGAnalyticsNetMetrixTracker.h b/Sources/SRGAnalytics/SRGAnalyticsNetMetrixTracker.h deleted file mode 100644 index dd5469af..00000000 --- a/Sources/SRGAnalytics/SRGAnalyticsNetMetrixTracker.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) SRG SSR. All rights reserved. -// -// License information is available from the LICENSE file. -// - -#import "SRGAnalyticsConfiguration.h" - -@import Foundation; - -NS_ASSUME_NONNULL_BEGIN - -/** - * Tracker for NetMetrix related events. - */ -@interface SRGAnalyticsNetMetrixTracker : NSObject - -/** - * Create a tracker sending events for the specified configuration. - * - * @param configuration The configuration to use. - * - * @return The Netmetrix tracker. - */ -- (instancetype)initWithConfiguration:(SRGAnalyticsConfiguration *)configuration; - -/** - * Send a view event. - */ -- (void)trackView; - -@end - -@interface SRGAnalyticsNetMetrixTracker (Unavailable) - -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Sources/SRGAnalytics/SRGAnalyticsNetMetrixTracker.m b/Sources/SRGAnalytics/SRGAnalyticsNetMetrixTracker.m deleted file mode 100644 index c0aa7b59..00000000 --- a/Sources/SRGAnalytics/SRGAnalyticsNetMetrixTracker.m +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright (c) SRG SSR. All rights reserved. -// -// License information is available from the LICENSE file. -// - -#import "SRGAnalyticsNetMetrixTracker.h" - -#import "SRGAnalyticsLogger.h" -#import "SRGAnalyticsNotifications.h" -#import "SRGAnalyticsTracker.h" - -@import UIKit; - -@interface SRGAnalyticsNetMetrixTracker () - -@property (nonatomic, copy) SRGAnalyticsConfiguration *configuration; - -@end - -@implementation SRGAnalyticsNetMetrixTracker - -#pragma mark Object lifecycle - -- (instancetype)initWithConfiguration:(SRGAnalyticsConfiguration *)configuration -{ - if (self = [super init]) { - self.configuration = configuration; - } - return self; -} - -#pragma mark View tracking - -- (void)trackView -{ - SRGAnalyticsConfiguration *configuration = self.configuration; - NSString *netMetrixDomain = configuration.netMetrixDomain; - if (! netMetrixDomain) { - SRGAnalyticsLogInfo(@"NetMetrix", @"No NetMetrix domain is defined for this configuration. No event will be recorded"); - return; - } - - NSString *netMetrixURLString = [NSString stringWithFormat:@"https://%@.wemfbox.ch/cgi-bin/ivw/CP/apps/%@/%@/%@", netMetrixDomain, configuration.netMetrixIdentifier, self.platform.lowercaseString, self.device]; - NSURL *netMetrixURL = [NSURL URLWithString:netMetrixURLString]; - - NSURLComponents *URLComponents = [NSURLComponents componentsWithURL:netMetrixURL resolvingAgainstBaseURL:NO]; - URLComponents.queryItems = @[ [NSURLQueryItem queryItemWithName:@"d" value:@(arc4random()).stringValue] ]; - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URLComponents.URL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30.]; - [request setHTTPMethod:@"GET"]; - [request setValue:@"image/gif" forHTTPHeaderField:@"Accept"]; - - // Which User-Agent MUST be used is defined at https://www.net-metrix.ch/fr/service/directives/directives-supplementaires-pour-les-applications - NSString *userAgent = [NSString stringWithFormat:@"Mozilla/5.0 (%@-%@; U; CPU %@ like Mac OS X)", self.platform, self.device, self.operatingSystem]; - [request setValue:userAgent forHTTPHeaderField:@"User-Agent"]; - - // The app language must be sent, not the device language. This is sadly not documented in https://www.net-metrix.ch/fr/service/directives/directives-supplementaires-pour-les-applications, - // but this information was obtained from a NetMetrix technician. - [request setValue:NSBundle.mainBundle.preferredLocalizations.firstObject forHTTPHeaderField:@"Accept-Language"]; - - SRGAnalyticsLogDebug(@"NetMetrix", @"Request %@ started", request.URL); - [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { - SRGAnalyticsLogDebug(@"NetMetrix", @"Request %@ ended with error %@", request.URL, error); - }] resume]; -} - -#pragma mark Information - -- (NSString *)platform -{ -#if TARGET_OS_TV - return @"tvOS"; -#else - return @"iOS"; -#endif -} - -- (NSString *)device -{ -#if TARGET_OS_TV - return @"tv"; -#else - if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone) { - return @"phone"; - } - else if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { - return @"tablet"; - } - else { - return @"universal"; - } -#endif -} - -- (NSString *)operatingSystem -{ -#if TARGET_OS_TV - return @"Apple TV OS"; -#else - if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone) { - return @"iPhone OS"; - } - else if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { - return @"iPad OS"; - } - else { - return @"OS"; - } -#endif -} - -@end diff --git a/Sources/SRGAnalytics/SRGAnalyticsNotifications.m b/Sources/SRGAnalytics/SRGAnalyticsNotifications.m index 388b70aa..5afb45d9 100644 --- a/Sources/SRGAnalytics/SRGAnalyticsNotifications.m +++ b/Sources/SRGAnalytics/SRGAnalyticsNotifications.m @@ -16,9 +16,6 @@ NSString * const SRGAnalyticsComScoreRequestNotification = @"SRGAnalyticsComScoreRequestNotification"; NSString * const SRGAnalyticsComScoreLabelsKey = @"SRGAnalyticsComScoreLabels"; -NSString * const SRGAnalyticsNetmetrixRequestNotification = @"SRGAnalyticsNetmetrixRequestNotification"; -NSString * const SRGAnalyticsNetmetrixURLKey = @"SRGAnalyticsNetmetrixURL"; - static NSDictionary *SRGAnalyticsProxyLabelsFromURLComponents(NSURLComponents *URLComponents) { NSMutableDictionary *labels = [NSMutableDictionary dictionary]; @@ -47,11 +44,6 @@ - (NSURLSessionDataTask *)srganalytics_swizzled_dataTaskWithRequest:(NSURLReques userInfo:@{ SRGAnalyticsComScoreLabelsKey : SRGAnalyticsProxyLabelsFromURLComponents(URLComponents) }]; } - else if ([host containsString:@"wemfbox"]) { - [NSNotificationCenter.defaultCenter postNotificationName:SRGAnalyticsNetmetrixRequestNotification - object:nil - userInfo:@{ SRGAnalyticsNetmetrixURLKey : URL }]; - } return [self srganalytics_swizzled_dataTaskWithRequest:request completionHandler:completionHandler]; } diff --git a/Sources/SRGAnalytics/SRGAnalyticsTracker.m b/Sources/SRGAnalytics/SRGAnalyticsTracker.m index 9009c422..435aca7b 100644 --- a/Sources/SRGAnalytics/SRGAnalyticsTracker.m +++ b/Sources/SRGAnalytics/SRGAnalyticsTracker.m @@ -11,7 +11,6 @@ #import "SRGAnalytics.h" #import "SRGAnalyticsLabels+Private.h" #import "SRGAnalyticsLogger.h" -#import "SRGAnalyticsNetMetrixTracker.h" #import "SRGAnalyticsNotifications+Private.h" #import "UIViewController+SRGAnalytics.h" @@ -44,7 +43,6 @@ @interface SRGAnalyticsTracker () @property (nonatomic, copy) SRGAnalyticsConfiguration *configuration; @property (nonatomic) TagCommander *tagCommander; -@property (nonatomic) SRGAnalyticsNetMetrixTracker *netmetrixTracker; @property (nonatomic) SCORStreamingAnalytics *streamSense; @property (nonatomic) SRGAnalyticsLabels *globalLabels; @@ -85,7 +83,7 @@ - (void)startWithConfiguration:(SRGAnalyticsConfiguration *)configuration builder.secureTransmissionEnabled = YES; builder.persistentLabels = [self persistentComScoreLabels]; - // See https://srfmmz.atlassian.net/wiki/spaces/INTFORSCHUNG/pages/721420782/ComScore+-+Media+Metrix+Report + // See https://confluence.srg.beecollaboration.com/display/INTFORSCHUNG/ComScore+-+Media+Metrix+Report // Coding Document for Video Players, page 16 builder.httpRedirectCachingEnabled = NO; @@ -207,12 +205,6 @@ - (void)trackPageViewWithTitle:(NSString *)title [self trackTagCommanderPageViewWithTitle:title levels:levels labels:labels fromPushNotification:fromPushNotification]; [self trackComScorePageViewWithTitle:title levels:levels labels:labels fromPushNotification:fromPushNotification]; - - if (! self.netmetrixTracker) { - self.netmetrixTracker = [[SRGAnalyticsNetMetrixTracker alloc] initWithConfiguration:self.configuration]; - } - - [self.netmetrixTracker trackView]; } - (void)trackComScorePageViewWithTitle:(NSString *)title @@ -351,7 +343,7 @@ - (void)sendApplicationList { // Tracks which SRG SSR applications are installed on the user device // - // Specifications are available at: https://srfmmz.atlassian.net/wiki/display/INTFORSCHUNG/App+Overlapping+Measurement + // Specifications are available at: https://confluence.srg.beecollaboration.com/display/INTFORSCHUNG/App+Overlapping+Measurement // // This measurement is not critical and is therefore performed only once the tracker starts. If it fails for some reason // (no network, for example), the measurement will be attempted again the next time the application is started diff --git a/Sources/SRGAnalytics/include/SRGAnalyticsConfiguration.h b/Sources/SRGAnalytics/include/SRGAnalyticsConfiguration.h index d99ca802..e0c3e91b 100644 --- a/Sources/SRGAnalytics/include/SRGAnalyticsConfiguration.h +++ b/Sources/SRGAnalytics/include/SRGAnalyticsConfiguration.h @@ -57,12 +57,10 @@ typedef NS_ENUM(NSInteger, SRGAnalyticsEnvironmentMode) { * business unit which publishes the application. * @param container The TagCommander container identifier to which measurements will be sent. * @param siteName The name of the site which measurements must be associated with. - * @param netMetrixIdentifier The NetMetrix application identifier to send measurements for. */ - (instancetype)initWithBusinessUnitIdentifier:(SRGAnalyticsBusinessUnitIdentifier)businessUnitIdentifier container:(NSInteger)container - siteName:(NSString *)siteName - netMetrixIdentifier:(NSString *)netMetrixIdentifier; + siteName:(NSString *)siteName; /** * Set to `YES` if measurements are studied by the General SRG SSR Direction, or to `NO` if the business @@ -114,16 +112,6 @@ typedef NS_ENUM(NSInteger, SRGAnalyticsEnvironmentMode) { */ @property (nonatomic, readonly, copy) NSString *siteName; -/** - * The NetMetrix domain. - */ -@property (nonatomic, readonly, copy, nullable) NSString *netMetrixDomain; - -/** - * The NetMetrix application identifier. - */ -@property (nonatomic, readonly, copy) NSString *netMetrixIdentifier; - /** * The analytics environment. */ diff --git a/Sources/SRGAnalytics/include/SRGAnalyticsLabels.h b/Sources/SRGAnalytics/include/SRGAnalyticsLabels.h index 35f2fa67..1e265093 100644 --- a/Sources/SRGAnalytics/include/SRGAnalyticsLabels.h +++ b/Sources/SRGAnalytics/include/SRGAnalyticsLabels.h @@ -14,8 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SRGAnalyticsLabels : NSObject /** - * Additional custom information, mapping variables to values. See https://srfmmz.atlassian.net/wiki/spaces/INTFORSCHUNG/pages/197019081 - * for a full list of possible variable names. + * Additional custom information, mapping variables to values. * * You should rarely need to provide custom information with measurements, as this requires the variable name to be * declared on TagCommander portal first (otherwise the associated value will be discarded). @@ -25,8 +24,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, nullable) NSDictionary *customInfo; /** - * Additional custom information to be sent to comScore. See https://srfmmz.atlassian.net/wiki/spaces/SRGPLAY/pages/36077617/Measurement+of+SRG+Player+Apps - * for a full list of possible variable names. + * Additional custom information to be sent to comScore. * * Custom information can be used to override official labels. You should use this ability sparingly, though. */ diff --git a/Sources/SRGAnalytics/include/SRGAnalyticsNotifications.h b/Sources/SRGAnalytics/include/SRGAnalyticsNotifications.h index 28868ff8..19688bbc 100644 --- a/Sources/SRGAnalytics/include/SRGAnalyticsNotifications.h +++ b/Sources/SRGAnalytics/include/SRGAnalyticsNotifications.h @@ -9,8 +9,8 @@ NS_ASSUME_NONNULL_BEGIN /** - * The following notifications can be used if you need to track when TagCommander, comScore and NetMetrix - * requests are made, and which information will be sent to these services, for unit testing purposes. + * The following notifications can be used if you need to track when TagCommander and comScore requests are made, + * and which information will be sent to these services, for unit testing purposes. * * These notifications are only emitted when enabling the `unitTesting` tracker configuration flag, @see * `SRGAnalyticsConfiguration`. @@ -30,12 +30,6 @@ OBJC_EXPORT NSString * const SRGAnalyticsComScoreRequestNotification; // Information available for `SRGAnalyticsComScoreRequestNotification`. OBJC_EXPORT NSString * const SRGAnalyticsComScoreLabelsKey; // Key for accessing the comScore labels (as an `NSDictionary`) available from the user info. -// Notification sent when a request is made to NetMetrix. -OBJC_EXPORT NSString * const SRGAnalyticsNetmetrixRequestNotification; - -// Information available for `SRGAnalyticsNetmetrixRequestNotification`. -OBJC_EXPORT NSString * const SRGAnalyticsNetmetrixURLKey; - /** * Get the currrent unique identifier added to all measurements made in unit testing mode. */ diff --git a/Sources/SRGAnalytics/include/SRGAnalyticsTracker.h b/Sources/SRGAnalytics/include/SRGAnalyticsTracker.h index 60f2e5f5..b3196f7c 100644 --- a/Sources/SRGAnalytics/include/SRGAnalyticsTracker.h +++ b/Sources/SRGAnalytics/include/SRGAnalyticsTracker.h @@ -14,8 +14,9 @@ NS_ASSUME_NONNULL_BEGIN /** * The analytics tracker is a singleton instance responsible of tracking usage of an application, sending measurements - * to TagCommander, comScore and NetMetrix. The usage data is simply a collection of key-values (both strings), named - * labels, which can then be used by data analysts in studies and reports. + * to TagCommander (internal analytics) and comScore (Mediapulse official audience measurements). The usage data is + * simply a collection of key-values (both strings), named labels, which can then be used by data analysts in studies + * and reports. * * The analytics tracker implementation follows the SRG SSR guidelines for application measurements (mostly label name * conventions) and is therefore only intended for use by applications produced under the SRG SSR umbrella. @@ -69,8 +70,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Start the tracker. This is required to specify for which business unit you are tracking events, as well as to - * where they must be sent on the comScore, NetMetrix and TagCommander services. Attempting to track view, hidden - * or stream events without starting the tracker has no effect. + * where they must be sent on the comScore and TagCommander services. Attempting to track view, hidden or stream + * events without starting the tracker has no effect. * * @param configuration The configuration to use. This configuration is copied and cannot be changed afterwards. */ diff --git a/Tests/SRGAnalyticsIdentity-tests.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Tests/SRGAnalyticsIdentity-tests.xcworkspace/xcshareddata/swiftpm/Package.resolved index c84cb954..d6452815 100644 --- a/Tests/SRGAnalyticsIdentity-tests.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Tests/SRGAnalyticsIdentity-tests.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -3,11 +3,11 @@ "pins": [ { "package": "ComScore", - "repositoryURL": "https://github.com/SRGSSR/ComScore-xcframework-apple.git", + "repositoryURL": "https://github.com/comScore/Comscore-Swift-Package-Manager.git", "state": { "branch": null, - "revision": "b5dc5dc60435f363a744e17975957361c844aa38", - "version": "6.6.0" + "revision": "805ef197755a66e634fccb5d23d9068ca5c1f395", + "version": "6.7.0" } }, { @@ -51,8 +51,8 @@ "repositoryURL": "https://github.com/AliSoftware/OHHTTPStubs.git", "state": { "branch": null, - "revision": "e92b5a5746ef16add2a1424f1fc19529d9a75cde", - "version": "9.0.0" + "revision": "12f19662426d0434d6c330c6974d53e2eb10ecd9", + "version": "9.1.0" } }, { @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgappearance-apple.git", "state": { "branch": null, - "revision": "80ebf882d46451001c1fd7d3e21baa264ad88477", - "version": "3.0.1" + "revision": "1e635509b57626073cfff3d74037214e2e42e6e5", + "version": "3.0.2" } }, { @@ -69,8 +69,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgcontentprotection-apple.git", "state": { "branch": null, - "revision": "596f4161b4460fc648d30d5d3ca2c16f249863ef", - "version": "3.0.1" + "revision": "a839c5343c8789f33c34d07d2a24a7de6eb4c054", + "version": "3.0.3" } }, { @@ -78,8 +78,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgdataprovider-apple.git", "state": { "branch": null, - "revision": "02673482b77adacbcdeac82db60116f893d2d817", - "version": "9.1.0" + "revision": "6556ac22f611b1f4913264ebb20f513165b0f748", + "version": "10.0.0" } }, { @@ -87,8 +87,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgdiagnostics-apple.git", "state": { "branch": null, - "revision": "5d2ef5c833a5cf6e56762a9c506e73f58ccad5e8", - "version": "3.0.0" + "revision": "ca2fe9329aa174281ac97bd4630096ff7cf41d58", + "version": "3.0.1" } }, { @@ -96,8 +96,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgidentity-apple.git", "state": { "branch": null, - "revision": "e1fe679ea1aefb5b4c80445ae70aa86b9a497aea", - "version": "3.0.0" + "revision": "4b5db1151c7f15364665cbfbc28dfce5b60cfceb", + "version": "3.0.3" } }, { @@ -105,8 +105,8 @@ "repositoryURL": "https://github.com/SRGSSR/srglogger-apple.git", "state": { "branch": null, - "revision": "cfc39d1223ed039aeb7df38c6c7570977b22d1aa", - "version": "3.0.0" + "revision": "9e5bf082222f5499996b931a8651aac6ea17ba4a", + "version": "3.0.1" } }, { @@ -114,8 +114,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgmediaplayer-apple.git", "state": { "branch": null, - "revision": "a0f192296817d471fbe48dc8623ab851a9266369", - "version": "6.1.0" + "revision": "7ba6b8f78205ec9186d67aa9d1c40e376ffd4909", + "version": "6.1.2" } }, { @@ -123,8 +123,8 @@ "repositoryURL": "https://github.com/SRGSSR/srgnetwork-apple.git", "state": { "branch": null, - "revision": "734fe399088b2f846e9e69d48a43118f6a8dc0d2", - "version": "3.0.0" + "revision": "76a83f3b6219f501b589317f8cc0a11556e0565a", + "version": "3.0.1" } }, { diff --git a/Tests/SRGAnalyticsIdentityTests/IdentityTestCase.m b/Tests/SRGAnalyticsIdentityTests/IdentityTestCase.m index 3a08a427..e4efbbb5 100644 --- a/Tests/SRGAnalyticsIdentityTests/IdentityTestCase.m +++ b/Tests/SRGAnalyticsIdentityTests/IdentityTestCase.m @@ -18,8 +18,7 @@ { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierRTS container:10 - siteName:@"rts-app-test-v" - netMetrixIdentifier:@"test"]; + siteName:@"rts-app-test-v"]; configuration.unitTesting = YES; return configuration; } diff --git a/Tests/SRGAnalyticsTests/ConfigurationTestCase.m b/Tests/SRGAnalyticsTests/ConfigurationTestCase.m index 7c95a7b4..8a395e9b 100644 --- a/Tests/SRGAnalyticsTests/ConfigurationTestCase.m +++ b/Tests/SRGAnalyticsTests/ConfigurationTestCase.m @@ -18,15 +18,13 @@ - (void)testCreation { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierSRF container:7 - siteName:@"site-name" - netMetrixIdentifier:@"netmetrix-identifier"]; + siteName:@"site-name"]; XCTAssertTrue(configuration.centralized); XCTAssertFalse(configuration.unitTesting); XCTAssertEqualObjects(configuration.businessUnitIdentifier, SRGAnalyticsBusinessUnitIdentifierSRF); XCTAssertEqual(configuration.site, 3666); XCTAssertEqual(configuration.container, 7); XCTAssertEqualObjects(configuration.siteName, @"site-name"); - XCTAssertEqualObjects(configuration.netMetrixIdentifier, @"netmetrix-identifier"); XCTAssertEqual(configuration.environmentMode, SRGAnalyticsEnvironmentModeAutomatic); XCTAssertEqualObjects(configuration.environment, SRGAnalyticsEnvironmentPreProduction); } @@ -35,8 +33,7 @@ - (void)testBusinessUnitSpecificConfiguration { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierSRF container:7 - siteName:@"site-name" - netMetrixIdentifier:@"netmetrix-identifier"]; + siteName:@"site-name"]; configuration.centralized = NO; XCTAssertFalse(configuration.centralized); @@ -45,7 +42,6 @@ - (void)testBusinessUnitSpecificConfiguration XCTAssertEqual(configuration.site, 3667); XCTAssertEqual(configuration.container, 7); XCTAssertEqualObjects(configuration.siteName, @"site-name"); - XCTAssertEqualObjects(configuration.netMetrixIdentifier, @"netmetrix-identifier"); XCTAssertEqual(configuration.environmentMode, SRGAnalyticsEnvironmentModeAutomatic); XCTAssertEqualObjects(configuration.environment, SRGAnalyticsEnvironmentPreProduction); } @@ -54,8 +50,7 @@ - (void)testEnvironmentModePreProduction { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierSRF container:7 - siteName:@"site-name" - netMetrixIdentifier:@"netmetrix-identifier"]; + siteName:@"site-name"]; configuration.environmentMode = SRGAnalyticsEnvironmentModePreProduction; XCTAssertTrue(configuration.centralized); @@ -64,7 +59,6 @@ - (void)testEnvironmentModePreProduction XCTAssertEqual(configuration.site, 3666); XCTAssertEqual(configuration.container, 7); XCTAssertEqualObjects(configuration.siteName, @"site-name"); - XCTAssertEqualObjects(configuration.netMetrixIdentifier, @"netmetrix-identifier"); XCTAssertEqual(configuration.environmentMode, SRGAnalyticsEnvironmentModePreProduction); XCTAssertEqualObjects(configuration.environment, SRGAnalyticsEnvironmentPreProduction); } @@ -73,8 +67,7 @@ - (void)testEnvironmentModeProduction { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierSRF container:7 - siteName:@"site-name" - netMetrixIdentifier:@"netmetrix-identifier"]; + siteName:@"site-name"]; configuration.environmentMode = SRGAnalyticsEnvironmentModeProduction; XCTAssertTrue(configuration.centralized); @@ -83,7 +76,6 @@ - (void)testEnvironmentModeProduction XCTAssertEqual(configuration.site, 3666); XCTAssertEqual(configuration.container, 7); XCTAssertEqualObjects(configuration.siteName, @"site-name"); - XCTAssertEqualObjects(configuration.netMetrixIdentifier, @"netmetrix-identifier"); XCTAssertEqual(configuration.environmentMode, SRGAnalyticsEnvironmentModeProduction); XCTAssertEqualObjects(configuration.environment, @"prod"); } @@ -92,8 +84,7 @@ - (void)testUnitTestingConfiguration { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierSRF container:7 - siteName:@"site-name" - netMetrixIdentifier:@"netmetrix-identifier"]; + siteName:@"site-name"]; configuration.unitTesting = YES; XCTAssertTrue(configuration.centralized); @@ -102,7 +93,6 @@ - (void)testUnitTestingConfiguration XCTAssertEqual(configuration.site, 3666); XCTAssertEqual(configuration.container, 7); XCTAssertEqualObjects(configuration.siteName, @"site-name"); - XCTAssertEqualObjects(configuration.netMetrixIdentifier, @"netmetrix-identifier"); XCTAssertEqual(configuration.environmentMode, SRGAnalyticsEnvironmentModeAutomatic); XCTAssertEqualObjects(configuration.environment, SRGAnalyticsEnvironmentPreProduction); } @@ -111,8 +101,7 @@ - (void)testCopy { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierSRF container:7 - siteName:@"site-name" - netMetrixIdentifier:@"netmetrix-identifier"]; + siteName:@"site-name"]; configuration.centralized = YES; configuration.unitTesting = YES; @@ -123,7 +112,6 @@ - (void)testCopy XCTAssertEqual(configuration.site, configurationCopy.site); XCTAssertEqual(configuration.container, configurationCopy.container); XCTAssertEqualObjects(configuration.siteName, configurationCopy.siteName); - XCTAssertEqualObjects(configuration.netMetrixIdentifier, configurationCopy.netMetrixIdentifier); XCTAssertEqual(configuration.environmentMode, configurationCopy.environmentMode); XCTAssertEqualObjects(configuration.environment, configurationCopy.environment); } diff --git a/Tests/SRGAnalyticsTests/TrackerSingletonSetup.m b/Tests/SRGAnalyticsTests/TrackerSingletonSetup.m index f46a6e33..c43d577a 100644 --- a/Tests/SRGAnalyticsTests/TrackerSingletonSetup.m +++ b/Tests/SRGAnalyticsTests/TrackerSingletonSetup.m @@ -11,8 +11,7 @@ { SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierRTS container:10 - siteName:@"rts-app-test-v" - netMetrixIdentifier:@"test"]; + siteName:@"rts-app-test-v"]; configuration.unitTesting = YES; [SRGAnalyticsTracker.sharedTracker startWithConfiguration:configuration]; diff --git a/docs/GETTING_STARTED.md b/docs/GETTING_STARTED.md index 9569f577..70174d60 100644 --- a/docs/GETTING_STARTED.md +++ b/docs/GETTING_STARTED.md @@ -19,8 +19,7 @@ Before measurements can be collected, the tracker singleton responsible of all a SRGAnalyticsConfiguration *configuration = [[SRGAnalyticsConfiguration alloc] initWithBusinessUnitIdentifier:SRGAnalyticsBusinessUnitIdentifierSRF container:3 - siteName:@"srf-app-site" - netMetrixIdentifier:@"srf-app-identifier"]; + siteName:@"srf-app-site"]; [SRGAnalyticsTracker.sharedTracker startWithConfiguration:configuration]; // ... @@ -119,6 +118,12 @@ struct ContentView: View { } ``` +## Measuring page views (web views) + +SRG SSR websites must be in general tracked so that users of a web browser (Safari, Chrome, Edge, etc.) are tracked. When displayed by an app in a web view, however, an SRG SSR website must not be tracked. + +An app can perform a native page view when a web view is displayed, but this is entirely optional. What is important is that no measurements are emitted from web views. + ## Measuring application functionalities To measure any kind of application functionality, you typically use hidden events. Those can be emitted by calling the corresponding methods on the tracker singleton itself. For example, you could send the following event when the user taps on a player full-screen button within your application: diff --git a/docs/README.md b/docs/README.md index 772dbd77..e597b97c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,19 +1,19 @@ -[![SRG Analytics logo](README-images/logo.png)](https://github.com/SRGSSR/srganalytics-apple) +[![SRG Analytics logo](README-images/logo.png)](https://github.com/SRGSSR/srganalytics-apple) [![GitHub releases](https://img.shields.io/github/v/release/SRGSSR/srganalytics-apple)](https://github.com/SRGSSR/srganalytics-apple/releases) [![platform](https://img.shields.io/badge/platfom-ios%20%7C%20tvos-blue)](https://github.com/SRGSSR/srganalytics-apple) [![SPM compatible](https://img.shields.io/badge/SPM-compatible-4BC51D.svg?style=flat)](https://swift.org/package-manager) [![GitHub license](https://img.shields.io/github/license/SRGSSR/srganalytics-apple)](https://github.com/SRGSSR/srganalytics-apple/blob/master/LICENSE) ## About -The SRG Analytics library makes it easy to add usage tracking information to your iOS and tvOS applications, following the SRG SSR standards. +The SRG Analytics library makes it easy to add usage tracking information to your iOS and tvOS applications, following the SRG SSR standards. -Measurements are based on events emitted by the application and collected by TagCommander, comScore and NetMetrix. +Measurements are based on events emitted by the application and sent to TagCommander (for internal analytics purposes) as well as Mediapulse (for official audience measurements, via comScore). -The SRG Analytics library supports three kinds of measurements: +The SRG Analytics library supports three kinds of measurements: * View events: Appearance of views (page views), which makes it possible to track which content is seen by users. * Hidden events: Custom events which can be used for measurement of application functionalities. - * Stream playback events: Audio and video consumption measurements for application using our [SRG Media Player](https://github.com/SRGSSR/srgmediaplayer-apple). Additional playback information (title, duration, etc.) must be supplied externally. For application using our [SRG Data Provider](https://github.com/SRGSSR/srgdataprovider-apple) library, though, this process is entirely automated. - * Integration with our [SRG Identity](https://github.com/SRGSSR/srgidentity-apple) library. + * Stream playback events: Audio and video consumption measurements for application using our [SRG Media Player](https://github.com/SRGSSR/srgmediaplayer-apple). Additional playback information (title, duration, etc.) must be supplied externally. For application using our [SRG Data Provider](https://github.com/SRGSSR/srgdataprovider-apple) library, though, this process is entirely automated. + * Integration with our [SRG Identity](https://github.com/SRGSSR/srgidentity-apple) library. ## Compatibility @@ -32,17 +32,17 @@ The library must be integrated using [Swift Package Manager](https://swift.org/p The library is made of serveral smaller libraries. Which ones your project must link against depends on your needs: - If you only need basic view and hidden event tracking, just link against `SRGAnalytics`. If you need to track SwiftUI views link against `SRGAnalyticsSwiftUI` as well. -- If you need [SRG Media Player](https://github.com/SRGSSR/srgmediaplayer-apple) media playback tracking, also link against `SRGAnalyticsMediaPlayer`. -- If you need SRG standard media playback tracking with associated media metadata retrieved by [SRG Data Provider](https://github.com/SRGSSR/srgdataprovider-apple), also link against `SRGAnalyticsDataProvider`. This library provides several playback helpers you should use to ensure that context information is complete when playing a media. -- If you are using [SRG Identity](https://github.com/SRGSSR/srgidentity-apple) in your project, also link against `SRGAnalyticsIdentity`. +- If you need [SRG Media Player](https://github.com/SRGSSR/srgmediaplayer-apple) media playback tracking, also link against `SRGAnalyticsMediaPlayer`. +- If you need SRG standard media playback tracking with associated media metadata retrieved by [SRG Data Provider](https://github.com/SRGSSR/srgdataprovider-apple), also link against `SRGAnalyticsDataProvider`. This library provides several playback helpers you should use to ensure that context information is complete when playing a media. +- If you are using [SRG Identity](https://github.com/SRGSSR/srgidentity-apple) in your project, also link against `SRGAnalyticsIdentity`. ### Info.plist settings for application installation measurements -The library automatically tracks which SRG SSR applications are installed on a user device, and sends this information. For this mechanism to work properly, though, your application **must** declare all official SRG SSR application URL schemes as being supported in its `Info.plist` file. +The library automatically tracks which SRG SSR applications are installed on a user device, and sends this information. For this mechanism to work properly, though, your application **must** declare all official SRG SSR application URL schemes as being supported in its `Info.plist` file. This can be achieved as follows: -* Run the `LSApplicationQueriesSchemesGenerator.swift ` script found in the `Scripts` folder. This script automatically generates an `LSApplicationQueriesSchemesGenerator.plist` file in the folder you are running it from, containing an up-to-date list of SRG SSR application schemes. +* Run the `LSApplicationQueriesSchemesGenerator.swift ` script found in the `Scripts` folder. This script automatically generates an `LSApplicationQueriesSchemesGenerator.plist` file in the folder you are running it from, containing an up-to-date list of SRG SSR application schemes. * Open the generated `plist` file and either copy the `LSApplicationQueriesSchemes` to your project `Info.plist` file, or merge it with already existing entries. If URL schemes declared by your application do not match the current ones, application installations will not be accurately reported, and error messages will be logged when the application starts (see _Logging_ below). This situation is not catastropic but should be fixed when possible to ensure better measurements. @@ -78,7 +78,7 @@ To learn about how the library can be used, have a look at the [getting started ### Logging -The library internally uses the [SRG Logger](https://github.com/SRGSSR/srglogger-apple) library for logging, with the following subsystems: +The library internally uses the [SRG Logger](https://github.com/SRGSSR/srglogger-apple) library for logging, with the following subsystems: * `ch.srgssr.analytics` for `SRGAnalytics` events. * `ch.srgssr.analytics.mediaplayer` for `SRGAnalyticsMediaPlayer` events. diff --git a/fastlane/Fastfile b/fastlane/Fastfile index e317ebc8..e1e949f6 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -16,21 +16,32 @@ default_platform :ios platform :ios do before_all do ensure_git_status_clean - Dir.chdir('..') { sh 'make bootstrap' } + + xcversion(version: '~> 12') end desc 'Run library tests' lane :tests do clean_result_files - override_test_product_names + Device = Struct.new(:platform, :name) + TestBuild = Struct.new(:scheme, :scheme_suffix, :in_workspace) + + iphone11 = Device.new('iOS', 'iPhone 11') + appletv = Device.new('tvOS', 'Apple TV') + devices = [iphone11, appletv] + + scheme = swift_package_name + swift_package_tests = TestBuild.new(scheme, '-Package', false) + workspace_tests = TestBuild.new(scheme + 'Identity', '-tests', true) + test_builds = [swift_package_tests, workspace_tests] - run_tests_with_devices(['iPhone 11', 'Apple TV']) + # Run all tests on various simulators + srg_run_tests(devices, test_builds) - trainer( - path: './fastlane', - output_directory: './fastlane' - ) + # Produce JUnit files for CI + srg_trainer + override_junit_test_suite_names(test_builds) end after_all do @@ -43,73 +54,83 @@ platform :ios do end end -def clean_result_files - Dir['*.xml'].each { |file| File.delete(file) } - Dir['*.xcresult'].each { |folder| FileUtils.remove_entry(folder, true) } +def swift_package_name + JSON.parse((sh 'swift package dump-package'))['name'] end -# Override test product names to split iOS and tvOS test results -def override_test_product_names - set_xcconfig_value( - path: 'Tests/Tests.xcconfig', - name: 'PRODUCT_NAME[sdk=iphone*]', - value: '$(PROJECT_NAME)-iOS' - ) - set_xcconfig_value( - path: 'Tests/Tests.xcconfig', - name: 'PRODUCT_NAME[sdk=appletv*]', - value: '$(PROJECT_NAME)-tvOS' - ) +def clean_result_files + Dir['*.xml'].each { |file| File.delete(file) } + FileUtils.remove_entry('xcresult', true) end -def run_tests_with_devices(devices) +def srg_run_tests(devices, test_builds) devices.each do |device| - srg_scan(device) - copy_last_xcresult + test_builds.each do |test_build| + begin + srg_xcodebuild(device, test_build) + rescue StandardError => e + raise e unless e.message.include? '** TEST FAILED **' + + UI.important('One or more tests failed on ' + device.platform + ' (' + srg_xcodebuild_scheme(test_build) + '). ⚠️') + end + end end - check_xcresult_count(devices) end -def srg_scan(device) - scan( - device: device, - scheme: xcode_library_scheme, - output_types: '', - output_style: FastlaneCore::Env.truthy?('TRAVIS') ? 'raw' : 'standard', - fail_build: false, - clean: true +def srg_xcodebuild(device, test_build) + xcodebuild( + test: true, + workspace: srg_xcodebuild_workspace(test_build), + scheme: srg_xcodebuild_scheme(test_build), + destination: srg_xcodebuild_destination(device), + result_bundle_path: srg_xcodebuild_result_bundle_path(device, test_build) ) end -def xcresults_path - derived_data_path = lane_context[SharedValues::SCAN_DERIVED_DATA_PATH] - derived_data_path + '/Logs/Test/' +def srg_xcodebuild_workspace(test_build) + test_build.in_workspace ? 'Tests/' + srg_xcodebuild_scheme(test_build) + '.xcworkspace' : nil end -def copy_last_xcresult - file = nil - Dir.chdir(xcresults_path) do - # max == sort.last - file = Dir['*.xcresult'].max - end - file_name = File.basename(file) - FileUtils.copy_entry(xcresults_path + file_name, file_name) +def srg_xcodebuild_scheme(test_build) + test_build.scheme + test_build.scheme_suffix end -def check_xcresult_count(devices) - return unless Dir['*.xcresult'].count != devices.count +def srg_xcodebuild_destination(device) + 'platform=' + device.platform + ' Simulator,name=' + device.name +end - UI.user_error!('Whoops, unexpected xcresult file count.') +def srg_xcodebuild_result_bundle_path(device, test_build) + result_bundle_folder_path + test_build.scheme + '-' + device.platform +end + +# Convert xcresults to JUnit files +def srg_trainer + trainer( + path: result_bundle_folder_path, + output_directory: './fastlane', + fail_build: false + ) end -# Returns the library scheme -def xcode_library_scheme - scheme = nil - Dir.chdir('..') do - scheme = sh 'xcodebuild -list | grep "Schemes:" -A 1' +def result_bundle_folder_path + './fastlane/xcresult/' +end + +# Override JUnit test suite names to split iOS and tvOS test results +def override_junit_test_suite_names(test_builds) + test_builds.each do |test_build| + Dir[test_build.scheme + '-*.xml'].each do |file_name| + override_junit_test_suite_name(file_name) + end end - scheme ['Schemes:'] = '' - scheme.gsub(/\s+/, '').chomp +end + +def override_junit_test_suite_name(file_name) + platform = file_name.split('.').first.split('-').last + file = File.open(file_name, 'r') + xml = file.read.gsub('Tests" tests="', '-' + platform + '" tests="') + xml = xml.gsub('-tests" tests="', '-' + platform + '" tests="') + File.open(file_name, 'w') { |f| f.write(xml) } end # More information about multiple platforms in fastlane: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md diff --git a/fastlane/Pluginfile b/fastlane/Pluginfile index ac2f64ba..72dfbbd6 100644 --- a/fastlane/Pluginfile +++ b/fastlane/Pluginfile @@ -4,5 +4,4 @@ # # Ensure this file is checked in to source control! -gem 'fastlane-plugin-trainer', git: 'https://github.com/SRGSSR/trainer', tag: '0.9.1.1' -gem 'fastlane-plugin-xcconfig' +gem 'fastlane-plugin-trainer' diff --git a/fastlane/README.md b/fastlane/README.md index 26e446af..d2d323b0 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -12,7 +12,7 @@ Install _fastlane_ using ``` [sudo] gem install fastlane -NV ``` -or alternatively using `brew cask install fastlane` +or alternatively using `brew install fastlane` # Available Actions ## iOS