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

refactor!: singleton API only way to use SDK now #209

Merged
merged 16 commits into from Nov 17, 2022

Conversation

levibostian
Copy link
Member

@levibostian levibostian commented Nov 4, 2022

QA

This PR touches almost the entire codebase and during my own QA testing, I have found a few bugs. So, a full QA walk through with the RH app is recommended.

Things to test in particular:

  • Install build of RH app before pr.78 build. Run through the app a little bit to make sure some tasks are added to the background queue and profile and device token have been saved to app's data storage. Then, install pr.78 build of RH. Open app and make sure that the previously identified profile, device token, and background queue tasks all run as expected. This tests that customers upgrading to this version of SDK will not lose data going from SDK v2 to v3.
  • Open app, do some tasks, force quit app, open it up again. The SDK initialization code has been changed so we want to make sure that it's working correctly when the RH opens and it initializes the SDK.
  • Push notifications and in-app messages are received.
  • Profile and device attributes get added successfully to Fly. RH app adds these automatically. We need to confirm that Fly receives them.

Closes: https://github.com/customerio/issues/issues/6933

This PR removes the ability to use the iOS SDK in a non-singleton way. You used to be able to create 1+ instances of the SDK: CustomerIO() but now you have to use CustomerIO.shared.

Notes:

  • This PR will trigger a breaking change to the SDK and will trigger a major version bump to v3.0
  • This is a bigger PR since it's a larger refactor. I made comments on parts of the code I find interesting in the code review.

@codecov
Copy link

codecov bot commented Nov 4, 2022

Codecov Report

Merging #209 (dec4535) into develop (b8ba9b6) will decrease coverage by 1.54%.
The diff coverage is 44.16%.

@@             Coverage Diff             @@
##           develop     #209      +/-   ##
===========================================
- Coverage    52.30%   50.76%   -1.55%     
===========================================
  Files          101      102       +1     
  Lines         1172     1113      -59     
===========================================
- Hits           613      565      -48     
+ Misses         559      548      -11     
Impacted Files Coverage Δ
Sources/Common/Background Queue/Queue.swift 64.28% <ø> (ø)
Sources/Common/Background Queue/QueueStorage.swift 93.33% <ø> (ø)
...es/Common/Extensions/UIApplicationExtensions.swift 0.00% <ø> (ø)
Sources/Common/Service/HttpClient.swift 92.85% <ø> (ø)
Sources/Common/Type/Region.swift 100.00% <ø> (ø)
...es/Common/autogenerated/AutoLenses.generated.swift 13.15% <ø> (+1.79%) ⬆️
...ogenerated/AutoDependencyInjection.generated.swift 40.00% <0.00%> (+20.00%) ⬆️
...rces/MessagingPush/MessagingPush+AppDelegate.swift 0.00% <ø> (ø)
...essagingPush/RichPush/MessagingPush+RichPush.swift 0.00% <ø> (ø)
...essagingPush/RichPush/RichPushRequestHandler.swift 0.00% <ø> (ø)
... and 49 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Comment on lines -7 to -9
func appendSiteId(_ siteId: String)
// all site ids that have ever been registered with the SDK
var siteIds: [String] { get }
Copy link
Member Author

Choose a reason for hiding this comment

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

This code was originally added to the SDK so we could do something such as running background queue tasks for all of the site-ids ever registered to the SDK. Today, we only run background queue tasks for the currently initialized site-id (most to all of our customers use our SDK in this way).

However, we have never used this feature so I removed it. We can bring it back in the future if we decide we need this feature.

Comment on lines -70 to -78
public protocol SdkConfigStore: AutoMockable {
var config: SdkConfig { get set }
}

// sourcery: InjectRegister = "SdkConfigStore"
// sourcery: InjectSingleton
public class InMemorySdkConfigStore: SdkConfigStore {
@Atomic public var config = SdkConfig()
}
Copy link
Member Author

Choose a reason for hiding this comment

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

No more need for a SDK store. We now store the SDKConfig instance in the dependency injection graph.

import Foundation
import Gist

internal class MessagingInAppImplementation: MessagingInAppInstance {
Copy link
Member Author

Choose a reason for hiding this comment

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

All of this logic was copy/pasted from MessagingInApp class. To follow the same pattern that CustomerIO and MessagingPush classes follow with an implementation object.

Comment on lines +25 to +29
let sdkInitializedUtil = SdkInitializedUtilImpl()

guard let postSdkInitializedData = sdkInitializedUtil.postInitializedData else { return }

let diGraph = postSdkInitializedData.diGraph
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the new (safe) way to get the DiGraph instance. You see other files in this PR also doing it this way.

README.md Show resolved Hide resolved
siteIdPart = ".\(siteId)"
}

return "io.customer.sdk\(appUniqueIdentifier)\(siteIdPart)"
Copy link
Member Author

Choose a reason for hiding this comment

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

Reminder to self: QA test this to make sure that we are not changing the name after customer upgrades. To avoid customers losing data.

@ami-oss-ci
Copy link

ami-oss-ci commented Nov 4, 2022

Pull request title looks good 👍!

If this pull request gets merged, it will cause a new release of the software. Example: If this project's latest release version is 1.0.0. If this pull request gets merged in, the next release of this project will be 2.0.0. This pull request is a breaking change.

All merged pull requests will eventually get deployed. But some types of pull requests will trigger a deployment (such as features and bug fixes) while some pull requests will wait to get deployed until a later time.

To merge this pull request, add the label Ready to merge to this pull request and I'll merge it for you.

This project uses a special format for pull requests titles. Expand this section to learn more (expand by clicking the ᐅ symbol on the left side of this sentence)...

This project uses a special format for pull requests titles. Don't worry, it's easy!

This pull request title should be in this format:

<type>: short description of change being made

If your pull request introduces breaking changes to the code, use this format:

<type>!: short description of breaking change

where <type> is one of the following:

  • feat: - A feature is being added or modified by this pull request. Use this if you made any changes to any of the features of the project.

  • fix: - A bug is being fixed by this pull request. Use this if you made any fixes to bugs in the project.

  • docs: - This pull request is making documentation changes, only.

  • refactor: - A change was made that doesn't fix a bug or add a feature.

  • test: - Adds missing tests or fixes broken tests.

  • style: - Changes that do not effect the code (whitespace, linting, formatting, semi-colons, etc)

  • perf: - Changes improve performance of the code.

  • build: - Changes to the build system (maven, npm, gulp, etc)

  • ci: - Changes to the CI build system (Travis, GitHub Actions, Circle, etc)

  • chore: - Other changes to project that don't modify source code or test files.

  • revert: - Reverts a previous commit that was made.

Examples:

feat: edit profile photo
refactor!: remove deprecated v1 endpoints
build: update npm dependencies
style: run formatter 

Need more examples? Want to learn more about this format? Check out the official docs.

Note: If your pull request does multiple things such as adding a feature and makes changes to the CI server and fixes some bugs then you might want to consider splitting this pull request up into multiple smaller pull requests.

@ami-oss-ci
Copy link

ami-oss-ci commented Nov 4, 2022

Warnings
⚠️

I noticed file Tests/Tracking/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 
⚠️

I noticed file Tests/MessagingPushFCM/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 
⚠️

I noticed file Tests/MessagingPushAPN/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 

Generated by 🚫 dangerJS against b31ecbd

@levibostian levibostian self-assigned this Nov 4, 2022
Copy link

@jatinn jatinn left a comment

Choose a reason for hiding this comment

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

could use review from another engineer more familiar with swift.
overall looks fine main thing that feels odd to me is we pass both site id & di graph into many initialize calls which feels redundant as some dont use site id and since it seems like can get site id from the di graph.

README.md Show resolved Hide resolved
Sources/Common/Store/GlobalDataStore.swift Show resolved Hide resolved
/**
Base URL to use for the Customer.io track API. You will more then likely not modify this value.

If you override this value, `Region` set when initializing the SDK will be ignored.
*/
public var trackingApiUrl: String = ""
public var trackingApiUrl: String
Copy link

Choose a reason for hiding this comment

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

afaik swift cares about initialized & uninitialized variables. so before it was initialized to an empty string as a default, now that it is not any edge cases to consider if people dont set region?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure what you mean by, "...if people don't set region".

Having the default value be "" is error-prone, IMO. Our SDK should set a value for this when the SDK is initialized. So, by me removing the default, it reminds us to set a value for it at SDK initialization.

Sources/Common/Util/KeyValueStorage.swift Show resolved Hide resolved
Sources/Common/Util/KeyValueStorage.swift Show resolved Hide resolved
Sources/MessagingInApp/MessagingInAppImplementation.swift Outdated Show resolved Hide resolved

private func getDeliveryId(from message: Message) -> String? {
guard let deliveryId = message.gistProperties.campaignId else {
logger
Copy link

Choose a reason for hiding this comment

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

not sure if we want this as an error message as test delivery sends do not have delivery id set

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I would agree to not use an error log. Error logs are logs that we hope customers see and then report to us.

....knowing that delivery id is not set on test sends, I should probably make deliveryId optional for in-app event listener PR I made?

Sources/MessagingPush/MessagingPush.swift Outdated Show resolved Hide resolved
siteId: testSiteId,
deviceMetricsGrabber: deviceMetricsGrabberMock
)
newInstance.switchToGlobalDataStore()
Copy link

Choose a reason for hiding this comment

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

this just clears siteId so isnt this the same as UserDefaultsKeyValueStorage(deviceMetricsGrabber: deviceMetricsGrabberMock)

Copy link
Member Author

Choose a reason for hiding this comment

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

There are 2 required parameters of UserDefaultsKeyValueStorage constructor. So, I do not believe UserDefaultsKeyValueStorage(deviceMetricsGrabber: deviceMetricsGrabberMock) is possible.

Tests/Shared/UnitTest.swift Show resolved Hide resolved
@levibostian
Copy link
Member Author

@matt-frizzell came up with an idea of us waiting to deploy this change until this feature is merged as well.

@ami-oss-ci
Copy link

Warnings
⚠️

I noticed file Tests/MessagingPushAPN/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 
⚠️

I noticed file Tests/MessagingPushFCM/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 
⚠️

I noticed file Tests/Tracking/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 

Generated by 🚫 dangerJS against c208835

@ami-oss-ci
Copy link

Warnings
⚠️

I noticed file Tests/MessagingPushAPN/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 
⚠️

I noticed file Tests/MessagingPushFCM/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 
⚠️

I noticed file Tests/Tracking/APITest.swift was modified. That could mean that this pull request is introducing a breaking change to the SDK.

If this pull request does introduce a breaking change, make sure the pull request title is in the format:

<type>!: description of breaking change 
// Example:
refactor!: remove onComplete callback from async functions 

Generated by 🚫 dangerJS against dec4535

@levibostian levibostian merged commit 72b7477 into develop Nov 17, 2022
@levibostian levibostian deleted the levi/remove-multiple-sdk-instances branch November 17, 2022 18:01
ami-ci pushed a commit that referenced this pull request Nov 30, 2022
## [2.0.0-alpha.1](1.2.6...2.0.0-alpha.1) (2022-11-30)

### ⚠ BREAKING CHANGES

* make delivered push metric more reliable
* remove FCM dependency from cocoapods (#210)
* singleton API only way to use SDK now (#209)

### Bug Fixes

* fix compile time errors notification service extensions ([#214](#214)) ([bd5911b](bd5911b))
* make delivered push metric more reliable ([0478e52](0478e52))

### Code Refactoring

* remove FCM dependency from cocoapods ([#210](#210)) ([3547076](3547076))
* singleton API only way to use SDK now ([#209](#209)) ([72b7477](72b7477))
@ami-ci
Copy link
Contributor

ami-ci commented Nov 30, 2022

🎉 This PR is included in version 2.0.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

github-actions bot pushed a commit that referenced this pull request Dec 9, 2022
## [2.0.0-beta.1](1.2.7...2.0.0-beta.1) (2022-12-09)

### ⚠ BREAKING CHANGES

* make delivered push metric more reliable
* remove FCM dependency from cocoapods (#210)
* singleton API only way to use SDK now (#209)

### Bug Fixes

* add sdkwrapperconfig to rich push SDK config ([#226](#226)) ([e43b4cf](e43b4cf))
* do not modify custom attributes casing ([#234](#234)) ([8160fdf](8160fdf))
* fix compile time errors notification service extensions ([#214](#214)) ([bd5911b](bd5911b))
* make delivered push metric more reliable ([0478e52](0478e52))
* sdk not able to compile in ios app ([#225](#225)) ([e4d1b3f](e4d1b3f))

### Code Refactoring

* remove FCM dependency from cocoapods ([#210](#210)) ([3547076](3547076))
* singleton API only way to use SDK now ([#209](#209)) ([72b7477](72b7477))
github-actions bot pushed a commit that referenced this pull request Dec 13, 2022
## [2.0.0](1.2.7...2.0.0) (2022-12-13)

### ⚠ BREAKING CHANGES

* make delivered push metric more reliable
* remove FCM dependency from cocoapods (#210)
* singleton API only way to use SDK now (#209)

### Bug Fixes

* add sdkwrapperconfig to rich push SDK config ([#226](#226)) ([e43b4cf](e43b4cf))
* do not modify custom attributes casing ([#234](#234)) ([8160fdf](8160fdf))
* fix compile time errors notification service extensions ([#214](#214)) ([bd5911b](bd5911b))
* make delivered push metric more reliable ([0478e52](0478e52))
* sdk not able to compile in ios app ([#225](#225)) ([e4d1b3f](e4d1b3f))

### Code Refactoring

* remove FCM dependency from cocoapods ([#210](#210)) ([3547076](3547076))
* singleton API only way to use SDK now ([#209](#209)) ([72b7477](72b7477))
github-actions bot pushed a commit to nagyist/customerio-ios that referenced this pull request Feb 23, 2023
## [2.0.0](1.2.4...2.0.0) (2023-02-23)

### ⚠ BREAKING CHANGES

* make delivered push metric more reliable
* remove FCM dependency from cocoapods (customerio#210)
* singleton API only way to use SDK now (customerio#209)

### Features

* add in-app event listener ([customerio#211](https://github.com/nagyist/customerio-ios/issues/211)) ([737d43b](737d43b))
* in-app feature no longer requires orgId ([customerio#252](https://github.com/nagyist/customerio-ios/issues/252)) ([acd12da](acd12da))

### Bug Fixes

* access modifier for metric ([customerio#263](https://github.com/nagyist/customerio-ios/issues/263)) ([e641982](e641982))
* add sdkwrapperconfig to rich push SDK config ([customerio#226](https://github.com/nagyist/customerio-ios/issues/226)) ([e43b4cf](e43b4cf))
* added reusable code for wrapper SDKs ([customerio#247](https://github.com/nagyist/customerio-ios/issues/247)) ([36adf15](36adf15))
* async running BQ operations in loop ([customerio#250](https://github.com/nagyist/customerio-ios/issues/250)) ([f0a3d9c](f0a3d9c))
* device attributes shows sdk version instead of wrapper version ([e2462b9](e2462b9))
* do not modify custom attributes casing ([customerio#234](https://github.com/nagyist/customerio-ios/issues/234)) ([8160fdf](8160fdf))
* download rich push images from CDN ([customerio#237](https://github.com/nagyist/customerio-ios/issues/237)) ([b30cf02](b30cf02))
* fix compile time errors notification service extensions ([customerio#214](https://github.com/nagyist/customerio-ios/issues/214)) ([bd5911b](bd5911b))
* fix compile time errors notification service extensions ([customerio#216](https://github.com/nagyist/customerio-ios/issues/216)) ([6e8484a](6e8484a))
* in-app missing event ([customerio#259](https://github.com/nagyist/customerio-ios/issues/259)) ([43b3e97](43b3e97))
* make delivered push metric more reliable ([0478e52](0478e52))
* modify in-app event listener action parameters to new name ([customerio#255](https://github.com/nagyist/customerio-ios/issues/255)) ([b46528a](b46528a))
* prevent stackoverflow while executing background queue with lots of tasks in it ([customerio#245](https://github.com/nagyist/customerio-ios/issues/245)) ([ef0c428](ef0c428))
* push images and processing simple push ([customerio#230](https://github.com/nagyist/customerio-ios/issues/230)) ([f109f04](f109f04))
* region visibility modifier to be used by wrappers ([customerio#260](https://github.com/nagyist/customerio-ios/issues/260)) ([f0edfbc](f0edfbc))
* revert 2.0.2 as it was found unstable ([customerio#249](https://github.com/nagyist/customerio-ios/issues/249)) ([51b5831](51b5831))
* sdk not able to compile in ios app ([customerio#225](https://github.com/nagyist/customerio-ios/issues/225)) ([e4d1b3f](e4d1b3f))
* universal links deep links open host app ([customerio#268](https://github.com/nagyist/customerio-ios/issues/268)) ([29c95b5](29c95b5))
* universal links when touch a push notification open host app ([customerio#265](https://github.com/nagyist/customerio-ios/issues/265)) ([7dcaf73](7dcaf73))
* update the gist version in podspec ([customerio#256](https://github.com/nagyist/customerio-ios/issues/256)) ([5451488](5451488))

### Code Refactoring

* remove FCM dependency from cocoapods ([customerio#210](https://github.com/nagyist/customerio-ios/issues/210)) ([3547076](3547076))
* singleton API only way to use SDK now ([customerio#209](https://github.com/nagyist/customerio-ios/issues/209)) ([72b7477](72b7477))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants