Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: separate data pipeline module #415

Merged
merged 29 commits into from
Nov 29, 2023

Conversation

Shahroz16
Copy link
Contributor

@Shahroz16 Shahroz16 commented Nov 27, 2023

PR for [CDP] iOS Native Refactor: Creation of Data-pipeline module#11646

Goal:
Have a separate module for Segment implementation Data Pipeline that we can utilize from Tracking and extension methods on the CustomerIO class, that customers can call.

Copy link

github-actions bot commented Nov 27, 2023

Sample app builds 📱

Below you will find the list of the latest versions of the sample apps. It's recommended to always download the latest builds of the sample apps to accurately test the pull request.


  • CocoaPods-FCM: Build failed. See CI job logs to determine the issue and try re-building.
  • APN-UIKit: Build failed. See CI job logs to determine the issue and try re-building.

@@ -41,7 +42,8 @@ let package = Package(
// https://web.archive.org/web/20220525200227/https://www.timc.dev/posts/understanding-swift-packages/
//
// Update to exact version until wrapper SDKs become part of testing pipeline.
.package(name: "Firebase", url: "https://github.com/firebase/firebase-ios-sdk.git", "8.7.0"..<"11.0.0")
.package(name: "Firebase", url: "https://github.com/firebase/firebase-ios-sdk.git", "8.7.0"..<"11.0.0"),
.package(name: "Segment", url: "https://github.com/segmentio/analytics-swift.git", .branch("main"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be changed to the forked version, rest should be the same

import Segment

extension Configuration {
static var defaultConfiguration: Configuration {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is dependent on the DIGraph work, so we can get either the write key or site id or API key to have the config initialized as default.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call-out.

Could you add a TODO or FIXME comment on this line stating that this file is going to change after some other PR is created?

import Segment

public enum CIODataPipeline {
private static var analytics: Analytics = .init(configuration: Configuration.defaultConfiguration)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analytics object can't be optional, as Segment always expect it be non nullable. CIODataPipeline will be initialized from CustomerIOImplementation on SDK launch so there shouldn't be a case where this would be nullable.

Package.swift Outdated
@@ -16,6 +16,7 @@ import Foundation
// Therefore, it's important that we only expose modules that we want customers to use. Internal modules should not be included in this array.
var products: [PackageDescription.Product] = [
.library(name: "Tracking", targets: ["CioTracking"]),
.library(name: "DataPipeline", targets: ["CioDataPipeline"]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.library(name: "DataPipeline", targets: ["CioDataPipeline"]),
.library(name: "DataPipeline", targets: ["CioDataPipelines"]),

Somewhat nit-picky, but important to me since it's customer facing.

Since we call the product "Data Pipelines" I think it makes sense for the public SDK module name to match that naming.

@@ -16,6 +16,7 @@ import Foundation
// Therefore, it's important that we only expose modules that we want customers to use. Internal modules should not be included in this array.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Friendly reminder to also update cocoapods files.

You will probably need to create a new podspec file, update CustomerIO.podspec file, and also update the CI cocoapods deployments script to deploy the new podspec file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call-out.

private init() {}

// Static method to access the singleton Analytics instance.
public static func shared() -> Analytics {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was expecting CIODataPipeline.shared to return an instance of CIODataPipeline but this is returning the Segment SDK instance.

Do we need to publicly expose the Segment SDK? If so, is shared the right name for exposing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we are to use the instance of Analytics in extension method of CustomerIO we need to have it as a static member of CIODataPipeline.

Open to naming it whatever makes the most sense, since this is not going to be accessed by the users directly, shared seemed like a good candidate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shared is a commonly used Swift name when naming singleton instances. I think that is what is throwing me off. If I saw Swift code CIODataPipeline.shared, I was assume that an instance of CIODataPipeline would be returned.

Instead of having this shared function, could we instead re-use the static Segment variable above?

public private(set) static var analytics: Analytics = .init(configuration: Configuration.defaultConfiguration)

Then, CIODataPipeline.analytics would do the same thing as CIODataPipeline.shared does currently.


// MARK: - System Modifiers

public extension CustomerIO {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am assuming that all of these extensions are added for Segment drop-in requirement?

If so, I think it would be good to move this extension block into another file to keep the drop-in code encapsulated somewhere.

One idea is using a common Swift pattern of using the file name to indicate it's purpose. Perhaps creating a new file CustomerIO+Segment.swift and putting this block of code inside could be helpful?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup that's correct, and that's a very good suggestion.


/// Retrieve the version of this library in use.
/// - Returns: A string representing the version in "BREAKING.FEATURE.FIX" format.
func version() -> String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to expose the Segment SDK version?

It feels weird to me for a customer to call CustomerIO.version and CIODataPipeline.version and get 2 different returned results? Also feels weird to expose the version of a dependency that our SDK has?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just feature matched the segments APIs, we can drop/keep or make any decisions in the ready for production tickets, otherwise the discussion might scope creep the PRs. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am OK with deciding later.

Idea: We make a decision in project slack channel? This seems like a short and quick decision to me. Could be answered async together.

import Segment

extension Configuration {
static var defaultConfiguration: Configuration {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call-out.

Could you add a TODO or FIXME comment on this line stating that this file is going to change after some other PR is created?

Comment on lines 7 to 9
// make a note in the docs on this that we removed the old "options" property
// and they need to write a middleware/enrichment now.
// the objc version should accomodate them if it's really needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// make a note in the docs on this that we removed the old "options" property
// and they need to write a middleware/enrichment now.
// the objc version should accomodate them if it's really needed.
// TODO: make a note in the docs on this that we removed the old "options" property
// and they need to write a middleware/enrichment now.
// the objc version should accomodate them if it's really needed.

Is this comment still valid? If so, I suggest adding TODO to make it easier to find and fix in a future PR.

Copy link
Contributor Author

@Shahroz16 Shahroz16 Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the comment from Segment about this method, i copied it right as is so we can make a more informed decision later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. If it's a comment for their codebase and not ours, I would consider removing it in this PR. To avoid confusing someone in the future like it did for me.

This is a non-blocker and you can decide what you think is best regarding what to do with this.


// MARK: - Typed Event Signatures

public extension CustomerIO {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a good idea to create an APITest for this new module. It has been really helpful to make sure that the public-facing API compiles for customers as intended.

If you agree, could you make sure this is added as a task to a CDP ticket to do this? It's OK if this is not part of this PR if that's out of scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I was thinking it could be added to Ready for Production tickets where we can add even more test cases related.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am OK with that.

If that's the case, could you add a // TODO or // FIXME comment to this file specifying that we are planning on that?

@Shahroz16 Shahroz16 marked this pull request as ready for review November 29, 2023 10:35
@Shahroz16 Shahroz16 merged commit 2c8f1d7 into main-replica-for-cdp Nov 29, 2023
@Shahroz16 Shahroz16 deleted the shahroz/datapipeline-module branch November 29, 2023 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants