Skip to content

Commit 38f052a

Browse files
authored
Merge pull request #33 from apivideo/feature/new-analytics
feat(player): use new analytics endpoint
2 parents 98f6ed8 + 9ba560f commit 38f052a

File tree

8 files changed

+91
-65
lines changed

8 files changed

+91
-65
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on: [push]
44

55
jobs:
66
test:
7-
runs-on: macos-latest
7+
runs-on: macos-13
88
steps:
99
- uses: actions/checkout@v3
1010
- name: Set API key

ApiVideoPlayer.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ Pod::Spec.new do |s|
1414
s.source_files = 'Sources/**/*.{swift, plist}'
1515
s.resources = 'Sources/**/*.{storyboard,xib,xcassets,json,png}'
1616

17-
s.dependency "ApiVideoPlayerAnalytics", "1.1.1"
17+
s.dependency "ApiVideoPlayerAnalytics", "2.0.0"
1818
end

ApiVideoPlayer.xcodeproj/project.pbxproj

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@
6565
21F14AE02C50E77A00B61588 /* ApiVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F14ABD2C50E77A00B61588 /* ApiVideoPlayer.swift */; };
6666
21F14AE12C50E77A00B61588 /* SwiftUIPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F14ABE2C50E77A00B61588 /* SwiftUIPlayerViewController.swift */; };
6767
21F14AE42C50E7E500B61588 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 21F14AE22C50E7E400B61588 /* Media.xcassets */; };
68+
21F2E1042C52981000E833C2 /* ApiVideoPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21BD67A82C51467B0039DEB6 /* ApiVideoPlayer.framework */; };
69+
21F2E1052C52981000E833C2 /* ApiVideoPlayer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 21BD67A82C51467B0039DEB6 /* ApiVideoPlayer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
70+
21F2E1082C52981800E833C2 /* ApiVideoPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21BD67A82C51467B0039DEB6 /* ApiVideoPlayer.framework */; };
71+
21F2E1092C52981800E833C2 /* ApiVideoPlayer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 21BD67A82C51467B0039DEB6 /* ApiVideoPlayer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
72+
21F2E10C2C52A28000E833C2 /* ApiVideoPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21BD67A82C51467B0039DEB6 /* ApiVideoPlayer.framework */; };
73+
21F2E10D2C52A28000E833C2 /* ApiVideoPlayer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 21BD67A82C51467B0039DEB6 /* ApiVideoPlayer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6874
/* End PBXBuildFile section */
6975

7076
/* Begin PBXContainerItemProxy section */
@@ -89,6 +95,27 @@
8995
remoteGlobalIDString = 21F149552C50DF0E00B61588;
9096
remoteInfo = ApiVidePlayer;
9197
};
98+
21F2E1062C52981000E833C2 /* PBXContainerItemProxy */ = {
99+
isa = PBXContainerItemProxy;
100+
containerPortal = 21F1494D2C50DF0E00B61588 /* Project object */;
101+
proxyType = 1;
102+
remoteGlobalIDString = 21F149552C50DF0E00B61588;
103+
remoteInfo = ApiVideoPlayer;
104+
};
105+
21F2E10A2C52981800E833C2 /* PBXContainerItemProxy */ = {
106+
isa = PBXContainerItemProxy;
107+
containerPortal = 21F1494D2C50DF0E00B61588 /* Project object */;
108+
proxyType = 1;
109+
remoteGlobalIDString = 21F149552C50DF0E00B61588;
110+
remoteInfo = ApiVideoPlayer;
111+
};
112+
21F2E10E2C52A28000E833C2 /* PBXContainerItemProxy */ = {
113+
isa = PBXContainerItemProxy;
114+
containerPortal = 21F1494D2C50DF0E00B61588 /* Project object */;
115+
proxyType = 1;
116+
remoteGlobalIDString = 21F149552C50DF0E00B61588;
117+
remoteInfo = ApiVideoPlayer;
118+
};
92119
/* End PBXContainerItemProxy section */
93120

94121
/* Begin PBXCopyFilesBuildPhase section */
@@ -98,6 +125,7 @@
98125
dstPath = "";
99126
dstSubfolderSpec = 10;
100127
files = (
128+
21F2E1052C52981000E833C2 /* ApiVideoPlayer.framework in Embed Frameworks */,
101129
);
102130
name = "Embed Frameworks";
103131
runOnlyForDeploymentPostprocessing = 0;
@@ -108,6 +136,18 @@
108136
dstPath = "";
109137
dstSubfolderSpec = 10;
110138
files = (
139+
21F2E1092C52981800E833C2 /* ApiVideoPlayer.framework in Embed Frameworks */,
140+
);
141+
name = "Embed Frameworks";
142+
runOnlyForDeploymentPostprocessing = 0;
143+
};
144+
21F2E1102C52A28000E833C2 /* Embed Frameworks */ = {
145+
isa = PBXCopyFilesBuildPhase;
146+
buildActionMask = 2147483647;
147+
dstPath = "";
148+
dstSubfolderSpec = 10;
149+
files = (
150+
21F2E10D2C52A28000E833C2 /* ApiVideoPlayer.framework in Embed Frameworks */,
111151
);
112152
name = "Embed Frameworks";
113153
runOnlyForDeploymentPostprocessing = 0;
@@ -209,6 +249,7 @@
209249
isa = PBXFrameworksBuildPhase;
210250
buildActionMask = 2147483647;
211251
files = (
252+
21F2E10C2C52A28000E833C2 /* ApiVideoPlayer.framework in Frameworks */,
212253
21B395962C51340900451CF1 /* ApiVideoClient in Frameworks */,
213254
);
214255
runOnlyForDeploymentPostprocessing = 0;
@@ -217,13 +258,15 @@
217258
isa = PBXFrameworksBuildPhase;
218259
buildActionMask = 2147483647;
219260
files = (
261+
21F2E1042C52981000E833C2 /* ApiVideoPlayer.framework in Frameworks */,
220262
);
221263
runOnlyForDeploymentPostprocessing = 0;
222264
};
223265
21F14A712C50E22200B61588 /* Frameworks */ = {
224266
isa = PBXFrameworksBuildPhase;
225267
buildActionMask = 2147483647;
226268
files = (
269+
21F2E1082C52981800E833C2 /* ApiVideoPlayer.framework in Frameworks */,
227270
);
228271
runOnlyForDeploymentPostprocessing = 0;
229272
};
@@ -285,6 +328,7 @@
285328
21BD67A82C51467B0039DEB6 /* ApiVideoPlayer.framework */,
286329
21BD67A92C51467B0039DEB6 /* Example iOS.app */,
287330
21BD67AA2C51467B0039DEB6 /* Example iOSSwiftUI.app */,
331+
21F2E1032C52981000E833C2 /* Frameworks */,
288332
);
289333
sourceTree = "<group>";
290334
};
@@ -499,6 +543,13 @@
499543
path = Resources;
500544
sourceTree = "<group>";
501545
};
546+
21F2E1032C52981000E833C2 /* Frameworks */ = {
547+
isa = PBXGroup;
548+
children = (
549+
);
550+
name = Frameworks;
551+
sourceTree = "<group>";
552+
};
502553
/* End PBXGroup section */
503554

504555
/* Begin PBXHeadersBuildPhase section */
@@ -540,11 +591,13 @@
540591
21F1495C2C50DF0F00B61588 /* Sources */,
541592
21F1495D2C50DF0F00B61588 /* Frameworks */,
542593
21F1495E2C50DF0F00B61588 /* Resources */,
594+
21F2E1102C52A28000E833C2 /* Embed Frameworks */,
543595
);
544596
buildRules = (
545597
);
546598
dependencies = (
547599
21F149632C50DF0F00B61588 /* PBXTargetDependency */,
600+
21F2E10F2C52A28000E833C2 /* PBXTargetDependency */,
548601
);
549602
name = ApiVideoPlayerTests;
550603
packageProductDependencies = (
@@ -567,6 +620,7 @@
567620
);
568621
dependencies = (
569622
21B395602C50EE0300451CF1 /* PBXTargetDependency */,
623+
21F2E1072C52981000E833C2 /* PBXTargetDependency */,
570624
);
571625
name = "Example iOS";
572626
productName = iOSExampleUIKit;
@@ -586,6 +640,7 @@
586640
);
587641
dependencies = (
588642
21B395652C50FA7B00451CF1 /* PBXTargetDependency */,
643+
21F2E10B2C52981800E833C2 /* PBXTargetDependency */,
589644
);
590645
name = "Example iOSSwiftUI";
591646
productName = iOSExampleSwiftUI;
@@ -776,6 +831,21 @@
776831
target = 21F149552C50DF0E00B61588 /* ApiVideoPlayer */;
777832
targetProxy = 21F149622C50DF0F00B61588 /* PBXContainerItemProxy */;
778833
};
834+
21F2E1072C52981000E833C2 /* PBXTargetDependency */ = {
835+
isa = PBXTargetDependency;
836+
target = 21F149552C50DF0E00B61588 /* ApiVideoPlayer */;
837+
targetProxy = 21F2E1062C52981000E833C2 /* PBXContainerItemProxy */;
838+
};
839+
21F2E10B2C52981800E833C2 /* PBXTargetDependency */ = {
840+
isa = PBXTargetDependency;
841+
target = 21F149552C50DF0E00B61588 /* ApiVideoPlayer */;
842+
targetProxy = 21F2E10A2C52981800E833C2 /* PBXContainerItemProxy */;
843+
};
844+
21F2E10F2C52A28000E833C2 /* PBXTargetDependency */ = {
845+
isa = PBXTargetDependency;
846+
target = 21F149552C50DF0E00B61588 /* ApiVideoPlayer */;
847+
targetProxy = 21F2E10E2C52A28000E833C2 /* PBXContainerItemProxy */;
848+
};
779849
/* End PBXTargetDependency section */
780850

781851
/* Begin PBXVariantGroup section */
@@ -1237,7 +1307,7 @@
12371307
repositoryURL = "https://github.com/apivideo/api.video-swift-player-analytics";
12381308
requirement = {
12391309
kind = exactVersion;
1240-
version = 1.1.1;
1310+
version = 2.0.0;
12411311
};
12421312
};
12431313
/* End XCRemoteSwiftPackageReference section */

ApiVideoPlayer.xcodeproj/xcshareddata/xcschemes/ApiVideoPlayer.xcscheme

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@
5353
debugDocumentVersioning = "YES"
5454
debugServiceExtension = "internal"
5555
allowLocationSimulation = "YES">
56+
<EnvironmentVariables>
57+
<EnvironmentVariable
58+
key = "IDEPreferLogStreaming"
59+
value = "YES"
60+
isEnabled = "YES">
61+
</EnvironmentVariable>
62+
</EnvironmentVariables>
5663
</LaunchAction>
5764
<ProfileAction
5865
buildConfiguration = "Release"

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ let package = Package(
1818
dependencies: [
1919
// Dependencies declare other packages that this package depends on.
2020
// .package(url: /* package url */, from: "1.0.0"),
21-
.package(url: "https://github.com/apivideo/api.video-swift-player-analytics", exact: "1.1.1"),
21+
.package(url: "https://github.com/apivideo/api.video-swift-player-analytics", exact: "2.0.0"),
2222
.package(url: "https://github.com/apivideo/api.video-swift-client", exact: "1.2.1")
2323
],
2424
targets: [

Sources/ApiVideoPlayer/Player/ApiVideoPlayerController.swift

Lines changed: 2 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import MediaPlayer
88
/// It is used internally of the ``ApiVideoPlayerView``.
99
/// It could be used directly if you want to use the player with a fully custom UI.
1010
public class ApiVideoPlayerController: NSObject {
11-
internal let player = AVPlayer(playerItem: nil)
12-
private var analytics: PlayerAnalytics?
11+
internal let player = ApiVideoAnalyticsAVPlayer(playerItem: nil)
1312
private var timeObserver: Any?
1413
private var isFirstPlay = true
1514
private var isSeeking = false
@@ -163,9 +162,7 @@ public class ApiVideoPlayerController: NSObject {
163162
name: .AVPlayerItemDidPlayToEndTime,
164163
object: playerItem
165164
)
166-
if let urlAsset = playerItem.asset as? AVURLAsset {
167-
self.setUpAnalytics(url: urlAsset.url.absoluteString)
168-
}
165+
169166
}
170167

171168
private func notifyError(error: Error) {
@@ -209,15 +206,6 @@ public class ApiVideoPlayerController: NSObject {
209206
player.removeTimeObserver(observer)
210207
}
211208

212-
private func setUpAnalytics(url: String) {
213-
do {
214-
let option = try Options(mediaUrl: url)
215-
self.analytics = PlayerAnalytics(options: option)
216-
} catch {
217-
print("Failed to initiate analytics for \(url)")
218-
}
219-
}
220-
221209
/// Get if the player is playing a live stream.
222210
/// - Returns: True if the player is playing a live stream
223211
public var isLive: Bool {
@@ -251,18 +239,7 @@ public class ApiVideoPlayerController: NSObject {
251239
}
252240

253241
private func seekImpl(to time: CMTime, completion: @escaping (Bool) -> Void) {
254-
let from = self.currentTime
255242
self.player.seek(to: time, toleranceBefore: .zero, toleranceAfter: .zero) { completed in
256-
self.analytics?
257-
.seek(
258-
from: Float(max(0, from.seconds)),
259-
to: Float(max(0, time.seconds))
260-
) { result in
261-
switch result {
262-
case .success: break
263-
case let .failure(error): print("Failed to send seek event to analytics: \(error)")
264-
}
265-
}
266243
self.infoNowPlaying.updateCurrentTime(currentTime: time)
267244
completion(completed)
268245
}
@@ -514,12 +491,6 @@ public class ApiVideoPlayerController: NSObject {
514491
self.replay()
515492
self.multicastDelegate.didLoop()
516493
}
517-
self.analytics?.end { result in
518-
switch result {
519-
case .success: break
520-
case let .failure(error): print("Failed to send end event to analytics: \(error)")
521-
}
522-
}
523494
self.multicastDelegate.didEnd()
524495
}
525496

@@ -578,12 +549,6 @@ public class ApiVideoPlayerController: NSObject {
578549
if self.autoplay {
579550
self.play()
580551
}
581-
self.analytics?.ready { result in
582-
switch result {
583-
case .success: break
584-
case let .failure(error): print("Failed to send ready event to analytics: \(error)")
585-
}
586-
}
587552
}
588553
}
589554

@@ -596,12 +561,6 @@ public class ApiVideoPlayerController: NSObject {
596561
return
597562
}
598563

599-
self.analytics?.pause { result in
600-
switch result {
601-
case .success: break
602-
case let .failure(error): print("Failed to send pause event to analytics: \(error)")
603-
}
604-
}
605564
self.infoNowPlaying.pause(currentTime: self.currentTime)
606565
self.multicastDelegate.didPause()
607566
}
@@ -623,19 +582,7 @@ public class ApiVideoPlayerController: NSObject {
623582
)
624583

625584
#endif
626-
self.analytics?.play { result in
627-
switch result {
628-
case .success: break
629-
case let .failure(error): print("Failed to send play event to analytics: \(error)")
630-
}
631-
}
632585
} else {
633-
self.analytics?.resume { result in
634-
switch result {
635-
case .success: break
636-
case let .failure(error): print("Failed to send resume event to analytics: \(error)")
637-
}
638-
}
639586
self.infoNowPlaying.play(currentTime: self.currentTime)
640587
}
641588
#if !os(macOS)

Tests/ApiVideoPlayerTests/IntegrationTests/AVPlayerExtensionsTests.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,27 @@ final class AVPlayerExtensions: XCTestCase {
1010
_ = observer.readyExpectation
1111

1212
let avPlayer = AVPlayer(playerItem: nil)
13+
avPlayer.addObserver(observer, forKeyPath: "status", options: .new, context: nil)
1314
avPlayer.replaceCurrentItem(withHls: VideoOptions(videoId: VideoId.validVideoId, videoType: .vod))
14-
avPlayer.currentItem?.addObserver(observer, forKeyPath: "status", options: .new, context: nil)
15+
1516
avPlayer.play()
1617

1718
waitForExpectations(timeout: 10, handler: nil)
18-
avPlayer.currentItem?.removeObserver(observer, forKeyPath: "status")
19+
avPlayer.removeObserver(observer, forKeyPath: "status")
1920
}
2021

2122
func testValidMP4VideoIdPlay() throws {
2223
let observer = AVPlayerReadyObserverImpl(testCase: self)
2324
_ = observer.readyExpectation
2425

2526
let avPlayer = AVPlayer(playerItem: nil)
27+
avPlayer.addObserver(observer, forKeyPath: "status", options: .new, context: nil)
2628
avPlayer.replaceCurrentItem(withMp4: VideoOptions(videoId: VideoId.validVideoId, videoType: .vod))
27-
avPlayer.currentItem?.addObserver(observer, forKeyPath: "status", options: .new, context: nil)
29+
2830
avPlayer.play()
2931

3032
waitForExpectations(timeout: 10, handler: nil)
31-
avPlayer.currentItem?.removeObserver(observer, forKeyPath: "status")
33+
avPlayer.removeObserver(observer, forKeyPath: "status")
3234
}
3335
}
3436

0 commit comments

Comments
 (0)