Skip to content

Added support for Target session Id setter & getter#115

Merged
swarna04 merged 5 commits intoadobe:dev-v3.2.0from
swarna04:MOB-16753-4
Jul 25, 2022
Merged

Added support for Target session Id setter & getter#115
swarna04 merged 5 commits intoadobe:dev-v3.2.0from
swarna04:MOB-16753-4

Conversation

@swarna04
Copy link
Copy Markdown
Contributor

Description

Ref: [MOB-16753], [MOB-16754]

Added Target session Id getter and setter APIs in the SDK to support hybrid implementations.

  • Added new public APIs getSessionId and setSessionId
  • Added unit, functional and integration tests to verify the functionality.

Related Issue

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@swarna04 swarna04 requested a review from PravinPK July 18, 2022 17:39
/// - Parameter id: a string containing the value of the Target session Id to be set in the SDK.
static func setSessionId(_ id: String?) {
let eventData = [TargetConstants.EventDataKeys.TARGET_SESSION_ID: id ?? ""]
let event = Event(name: TargetConstants.EventName.REQUEST_IDENTITY, type: EventType.target, source: EventSource.requestIdentity, data: eventData)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it would be nice to have the eventName be more evident, we can call them
"Set Target Session Id" rather than "TargetRequestIdentity" for all the API's

Griffon debugging would be easier

///
/// - Parameter completion: the callback `closure` invoked with the current session Id or `nil` if there was an error retrieving it.
static func getSessionId(_ completion: @escaping (String?, Error?) -> Void) {
let event = Event(name: TargetConstants.EventName.REQUEST_IDENTITY, type: EventType.target, source: EventSource.requestIdentity, data: nil)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Similar to above - EventName can be "Get Target Session Identifier" rather than "TargetRequestIdentity"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'd planned to clean up this code later but since you've mentioned I'll take it up here.

/// persisted for a period defined by `target.sessionTimeout` configuration setting.
///
/// - Parameter completion: the callback `closure` invoked with the current session Id or `nil` if there was an error retrieving it.
static func getSessionId(_ completion: @escaping (String?, Error?) -> Void) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

At some point, we should consider using Swift Result's as opposed to callback with optional String and Error
Docs:
https://www.hackingwithswift.com/articles/161/how-to-use-result-in-swift
https://developer.apple.com/documentation/swift/result

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure, it's probably a more elegant way to return multiple parameters in asynchronous APIs. I believe it does have some drawbacks in terms of Objective-C compatibility, however we could definitely explore more here.

/// This ID is preserved between app upgrades, is saved and restored during the standard application
/// backup process, and is removed at uninstall, upon privacy status update to opt out or when AEPTarget.resetExperience is called.
///
/// - Parameter id: a string containing the value of the Target session Id to be set in the SDK.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can also mention in the docs that an empty or nil sessionId value will reset the target session

setThirdPartyId(thirdPartyId: thirdPartyId, event: event)
} else {
dispatchRequestIdentityResponse(triggerEvent: event)
if let eventData = event.data {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A handful of functions in this file are missing docs.. May be we can update them in a later PR or have a JIRA created for them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll create a JIRA ticket to update any missing docs for existing methods outside of this work.

}

if sessionId != targetState.storedSessionId {
Log.trace(label: Target.LOG_TAG, "setSessionId - Updated Target session Id with the provided value \(sessionId).")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can this be Log.debug as well ?

}

private(set) var storedSessionId: String
#if DEBUG
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just checking:

Wondering if we can remove the if DEBUG flag and keep setting storedSessionId as still private
Aaand for the Functional Test, we can test setSessionId and GetSessionID together.. so we don't have to mock targetState.sessionId

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yup. I've revisited this code since we need to be able to update the sessionId from Target extension class as well. In summary, exposed another method in state that allows updating (and resetting) the session Id.

@swarna04 swarna04 requested a review from sbenedicadb July 20, 2022 15:51
@codecov
Copy link
Copy Markdown

codecov bot commented Jul 21, 2022

Codecov Report

Merging #115 (53a58b5) into dev-v3.2.0 (e2b4fda) will decrease coverage by 0.27%.
The diff coverage is 85.07%.

@@              Coverage Diff               @@
##           dev-v3.2.0     #115      +/-   ##
==============================================
- Coverage       90.40%   90.13%   -0.27%     
==============================================
  Files              24       24              
  Lines            1261     1307      +46     
==============================================
+ Hits             1140     1178      +38     
- Misses            121      129       +8     

Copy link
Copy Markdown
Member

@sbenedicadb sbenedicadb left a comment

Choose a reason for hiding this comment

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

looks good - a couple of small changes requested.

can we also update the objc test app with these new apis?

guard let responseEvent = responseEvent else {
let error = "Request to get Target session Id failed with error, \(TargetError.ERROR_TIMEOUT)"
completion(nil, TargetError(message: error))
Log.error(label: Target.LOG_TAG, error)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

error is too aggressive for these logs - we should scale these back to warnings

Log.error(label: Target.LOG_TAG, error)
return
}
guard let sessionId = eventData[TargetConstants.EventDataKeys.TARGET_SESSION_ID] as? String else {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

isn't it valid for there to be no session? i'm thinking this case should be handled differently.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There will always be a Target session (and a session Id). What scenario do you have in mind?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

prior to using target for the first time the session id is nil right?

also wondered if this getter should take timeout into consideration. i.e. - if there is a session id but it's expired, should calling this getter return nil?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, the session Id is generated upon the first Target request. Also, if the session has expired, the subsequent get call will return the new session Id generated by the SDK. This session Id is then used in all future Target requests and can also be passed to another channel to have the same session across.

/// - Parameters:
/// - sessionId: new session Id that needs to be set in the SDK
private func setSessionId(sessionId: String) {
if targetState.privacyStatusIsOptOut {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

given this is a block that returns, it should be switched to use the guard/else pattern

Comment on lines +36 to +44
private(set) var storedSessionId: String {
didSet {
if storedSessionId.isEmpty {
dataStore.remove(key: TargetConstants.DataStoreKeys.SESSION_ID)
} else {
dataStore.set(key: TargetConstants.DataStoreKeys.SESSION_ID, value: storedSessionId)
}
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i like this optimization 👍

@swarna04
Copy link
Copy Markdown
Contributor Author

can we also update the objc test app with these new apis?

The objC test app is updated for both sessionId and tntId as part of the other pr #116.

@swarna04 swarna04 merged commit b8f5213 into adobe:dev-v3.2.0 Jul 25, 2022
swarna04 added a commit that referenced this pull request Jul 29, 2022
* Added support for Target session Id setter & getter (#115)

* Added support for Target session Id setter/ getter

* code cleanup

* Fixed formatting issue

* Incorporated feedback

* Incorporated feedback

* Added support for TntId setter API (#116)

* Added support for Target session Id setter/ getter

* code cleanup

* Fixed formatting issue

* Added support for Target tntId setter

* code cleanup

* fixed formatting

* fixed definition conflict test issue

* Incorporated feedback

* Incorporated feedback

* Using distinct Event name

* More testapp updates

* Release prep v3.2.0 (#117)

* release prep v3.2.0

* Feedback updates

* Dependency and doc updates

* Incorporated feedback

* Fixed issue: Persisted edge host value was not used for Target request issued upon app close & relaunch (#119)

* Fixed an issue where persisted edge host value was not used for Target request issued upon app close & relaunch

* minor doc update

* Target doc updates (#120)

* Target doc updates

* docs cleanup
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.

3 participants