Skip to content

Commit b54c653

Browse files
authored
FirebaseAnalytics SwiftUI API for screen_view (#7562)
* FirebaseAnalytics SwiftUI API for `screen_view` This is a new FirebaseAnalyticsSwift SDK that adds native Swift extensions for FirebaseAnalytics, starting with a SwiftUI screen view function. * Formatting * CHANGELOG updates. * whitespace removal * Add podspec. * Add missing wrapper files. * Update copyright dates. * Update default class name. * Update versions and fix dependency name in podspec * Update version specified in the CHANGELOG * Add FirebaseAnalyticsSwift to GHA * Temporarily enable Analytics cron test. * Moving to the public version of Analytics * Move to source based pod testing. * Static framework
1 parent 2a5f555 commit b54c653

File tree

10 files changed

+221
-1
lines changed

10 files changed

+221
-1
lines changed

.github/workflows/analytics.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
pull_request:
55
paths:
66
- 'FirebaseAnalytics.podspec.json'
7+
- 'FirebaseAnalyticsSwift**'
78
- 'GoogleAppMeasurement.podspec.json'
89
- 'Gemfile'
910
schedule:
@@ -22,6 +23,8 @@ jobs:
2223
run: scripts/setup_bundler.sh
2324
- name: GoogleAppMeasurement
2425
run: scripts/third_party/travis/retry.sh pod spec lint GoogleAppMeasurement.podspec.json
26+
- name: FirebaseAnalyticsSwift
27+
run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseAnalyticsSwift.podspec --platforms=ios
2528

2629
# TODO: Consider pushing GoogleAppMeasurement.podspec.json to SpecsDev to enable similar test
2730
# for FirebaseAnalytics.podspec.json

.github/workflows/spm.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ jobs:
2929

3030
cron-only:
3131
# Don't run on private repo.
32-
if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk'
32+
# REVERT ME:
33+
# if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk'
3334

3435
runs-on: macOS-latest
3536
strategy:

.swiftpm/xcode/xcshareddata/xcschemes/Firebase-Package.xcscheme

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,48 @@
734734
ReferencedContainer = "container:">
735735
</BuildableReference>
736736
</BuildActionEntry>
737+
<BuildActionEntry
738+
buildForTesting = "YES"
739+
buildForRunning = "YES"
740+
buildForProfiling = "YES"
741+
buildForArchiving = "YES"
742+
buildForAnalyzing = "YES">
743+
<BuildableReference
744+
BuildableIdentifier = "primary"
745+
BlueprintIdentifier = "FirebaseAnalyticsSwift"
746+
BuildableName = "FirebaseAnalyticsSwift"
747+
BlueprintName = "FirebaseAnalyticsSwift"
748+
ReferencedContainer = "container:">
749+
</BuildableReference>
750+
</BuildActionEntry>
751+
<BuildActionEntry
752+
buildForTesting = "YES"
753+
buildForRunning = "YES"
754+
buildForProfiling = "YES"
755+
buildForArchiving = "YES"
756+
buildForAnalyzing = "YES">
757+
<BuildableReference
758+
BuildableIdentifier = "primary"
759+
BlueprintIdentifier = "FirebaseAnalyticsSwiftTarget"
760+
BuildableName = "FirebaseAnalyticsSwiftTarget"
761+
BlueprintName = "FirebaseAnalyticsSwiftTarget"
762+
ReferencedContainer = "container:">
763+
</BuildableReference>
764+
</BuildActionEntry>
765+
<BuildActionEntry
766+
buildForTesting = "YES"
767+
buildForRunning = "YES"
768+
buildForProfiling = "YES"
769+
buildForArchiving = "YES"
770+
buildForAnalyzing = "YES">
771+
<BuildableReference
772+
BuildableIdentifier = "primary"
773+
BlueprintIdentifier = "FirebaseAnalyticsSwift-Beta"
774+
BuildableName = "FirebaseAnalyticsSwift-Beta"
775+
BlueprintName = "FirebaseAnalyticsSwift-Beta"
776+
ReferencedContainer = "container:">
777+
</BuildableReference>
778+
</BuildActionEntry>
737779
</BuildActionEntries>
738780
</BuildAction>
739781
<TestAction

FirebaseAnalyticsSwift.podspec

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Pod::Spec.new do |s|
2+
s.name = 'FirebaseAnalyticsSwift'
3+
s.version = '7.9.0-beta'
4+
s.summary = 'Swift Extensions for Firebase Analytics'
5+
6+
s.description = <<-DESC
7+
Firebase Analytics is a free, out-of-the-box analytics solution that inspires actionable insights based on app usage and user engagement.
8+
DESC
9+
10+
s.homepage = 'https://firebase.google.com/features/analytics/'
11+
s.license = { :type => 'Apache', :file => 'LICENSE' }
12+
s.authors = 'Google, Inc.'
13+
14+
s.source = {
15+
:git => 'https://github.com/Firebase/firebase-ios-sdk.git',
16+
:tag => 'CocoaPods-' + s.version.to_s
17+
}
18+
19+
s.static_framework = true
20+
s.swift_version = '5.0'
21+
s.ios.deployment_target = '13.0'
22+
23+
s.cocoapods_version = '>= 1.10.0'
24+
s.prefix_header_file = false
25+
26+
s.source_files = [
27+
'FirebaseAnalyticsSwift/Sources/*.swift',
28+
]
29+
30+
s.dependency 'FirebaseAnalytics', '~> 7.7'
31+
end

FirebaseAnalyticsSwift/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Unreleased
2+
- Initial public beta release. Introduces new SwiftUI friendly APIs for
3+
screen tracking. To use, add `pod 'FirebaseAnalyticsSwift', '~> 7.9-beta'` to the Podfile or
4+
add the `FirebaseAnalyticsSwift-Beta` framework in Swift Package Manager, then
5+
and `import FirebaseAnalyticsSwift` to the source. Please provide feedback about
6+
these new APIs and suggestions about other potential Swift extensions to
7+
https://github.com/firebase/firebase-ios-sdk/issues.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#if canImport(SwiftUI)
16+
import FirebaseAnalytics
17+
import SwiftUI
18+
19+
/// Custom view modifier to allow for easily logging screen view events.
20+
@available(iOS 13, *)
21+
@available(tvOS, unavailable)
22+
@available(macOS, unavailable)
23+
@available(macCatalyst, unavailable)
24+
@available(watchOS, unavailable)
25+
internal struct LoggedAnalyticsModifier: ViewModifier {
26+
/// The name of the view to log in the `AnalyticsParameterScreenName` parameter.
27+
let screenName: String
28+
29+
/// The name of the view to log in the `AnalyticsParameterScreenClass` parameter.
30+
let screenClass: String
31+
32+
/// Extra parameters to log with the screen view event.
33+
let extraParameters: [String: Any]
34+
35+
func body(content: Content) -> some View {
36+
// Take the content and add an onAppear action to know when the view has appeared on screen.
37+
content.onAppear {
38+
// Log the event appearing, adding the appropriate keys and values needed for screen
39+
// view events.
40+
var parameters = extraParameters
41+
parameters[AnalyticsParameterScreenName] = screenName
42+
parameters[AnalyticsParameterScreenClass] = screenClass
43+
Analytics.logEvent(AnalyticsEventScreenView, parameters: parameters)
44+
}
45+
}
46+
}
47+
48+
@available(iOS 13, *)
49+
@available(tvOS, unavailable)
50+
@available(macOS, unavailable)
51+
@available(macCatalyst, unavailable)
52+
@available(watchOS, unavailable)
53+
public extension View {
54+
/// Logs `screen_view` events in Google Analytics for Firebase when this view appears on screen.
55+
/// - Parameters:
56+
/// - name: Current screen name logged with the `screen_view` event.
57+
/// - class: Current screen class or struct logged with the `screen_view` event.
58+
/// - extraParameters: Any additional parameters to be logged. These extra parameters must
59+
/// follow the same rules as described in the `Analytics.logEvent(_:parameters:)` docs.
60+
/// - Returns: A view with a custom `ViewModifier` used to log `screen_view` events when this
61+
/// view appears on screen.
62+
func analyticsScreen(name: String,
63+
class: String = "View",
64+
extraParameters: [String: Any] = [:]) -> some View {
65+
// `self` is the view, we're just adding an `LoggedAnalyticsModifier` modifier on it.
66+
modifier(LoggedAnalyticsModifier(screenName: name,
67+
screenClass: `class`,
68+
extraParameters: extraParameters))
69+
}
70+
}
71+
#endif

Package.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ let package = Package(
2727
name: "FirebaseAnalytics",
2828
targets: ["FirebaseAnalyticsTarget"]
2929
),
30+
.library(
31+
name: "FirebaseAnalyticsSwift-Beta",
32+
targets: ["FirebaseAnalyticsSwiftTarget"]
33+
),
3034
.library(
3135
name: "FirebaseAuth",
3236
targets: ["FirebaseAuth"]
@@ -250,6 +254,17 @@ let package = Package(
250254
url: "https://dl.google.com/firebase/ios/swiftpm/7.8.0/FirebaseAnalytics.zip",
251255
checksum: "1a833b113a8d877e978c4b4b55ad5ae7c7f10b148dc37f1321be7bb7e7053f3a"
252256
),
257+
.target(
258+
name: "FirebaseAnalyticsSwiftTarget",
259+
dependencies: [.target(name: "FirebaseAnalyticsSwift",
260+
condition: .when(platforms: [.iOS]))],
261+
path: "SwiftPM-PlatformExclude/FirebaseAnalyticsSwiftWrap"
262+
),
263+
.target(
264+
name: "FirebaseAnalyticsSwift",
265+
dependencies: ["FirebaseAnalyticsWrapper"],
266+
path: "FirebaseAnalyticsSwift/Sources"
267+
),
253268

254269
.target(
255270
name: "FirebaseAppDistributionTarget",
@@ -774,6 +789,7 @@ let package = Package(
774789
.testTarget(
775790
name: "analytics-import-test",
776791
dependencies: [
792+
"FirebaseAnalyticsSwiftTarget",
777793
"FirebaseAnalyticsWrapper",
778794
"Firebase",
779795
],
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#import <TargetConditionals.h>
16+
#if !TARGET_OS_IOS
17+
#warning "Firebase Analytics only supports the iOS platform"
18+
#endif
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Prevent a missing umbrella header warning.

SwiftPMTests/analytics-import-test/analytics-import.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,26 @@
1414

1515
import XCTest
1616
import FirebaseAnalytics
17+
#if canImport(SwiftUI)
18+
import SwiftUI
19+
import FirebaseAnalyticsSwift
20+
#endif
1721

1822
class importTest: XCTestCase {
1923
func testAnalyticsImported() {
2024
Analytics.logEvent(AnalyticsEventEcommercePurchase,
2125
parameters: [AnalyticsParameterShipping: 10.0])
2226
}
27+
28+
@available(iOS 13, *)
29+
@available(tvOS, unavailable)
30+
@available(macOS, unavailable)
31+
@available(macCatalyst, unavailable)
32+
@available(watchOS, unavailable)
33+
func testAnalyticsSwiftImported() {
34+
_ = Text("Hello, Analytics")
35+
.analyticsScreen(name: "analytics_text",
36+
class: "Greeting",
37+
extraParameters: ["greeted": true])
38+
}
2339
}

0 commit comments

Comments
 (0)