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

Makes SelfDescribingJson open #906

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

TwoDollarsEsq
Copy link

@TwoDollarsEsq TwoDollarsEsq commented Sep 17, 2024

This allows inheritance on the client side. This was the behaviour available with Objc version of the SDK and one I could not find any drawbacks of in the current state of the SDK. Being able to inherit allows the use of type's init while preserving SelfDescribingJson identity. This allows to put subclasses in place of SelfDescribingJson and still preserve types.

I've also checked that making SelfDescribing open works just as fine, though, it does require making a few helper types open as well. However, I haven't found similar applications for SelfDescribing as for SelfDescribingJson that would justify these side-effects. Hence, it's not included in this PR.

Example

Take a look at the wrapper I've been using for LinkClick events:

final class LinkClick: SelfDescribingJson {
    init?(
        elementId: String,
        targetUrl: String,
        elementContent: String,
        elementClasses: [ElementClass] = [],
        elementTarget: String = ""
    ) {
        var data = [String: Any]()
        
        if !elementId.isEmpty {
            data["elementId"] = elementId
        }
        if !targetUrl.isEmpty {
            data["targetUrl"] = targetUrl
        } else {
            assertionFailure("targetUrl is required by the schema.")
        }
        if !elementContent.isEmpty {
            data["elementContent"] = elementContent
        }
        if !elementClasses.isEmpty {
            data["elementClasses"] = elementClasses.map(\.rawValue)
        }
        if !elementTarget.isEmpty {
            data["elementTarget"] = elementTarget
        }
        
        super.init(
            schema: "iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1",
            andData: data as NSDictionary
        )
    }
    
    enum ElementClass {
        case toggle, link, button, custom(String)
        
        var rawValue: String {
            return switch self {
            case .toggle: "toggle"
            case .link: "link"
            case .button: "button"
            case .custom(let value): value
            }
        }
    }
}

It provides static type safety and ease of setting necessary parameters. At the same time I'm using event assemblies like this:

struct EventName: EventAssembly {
    let payload: SelfDescribingJson?
    let contexts: [SelfDescribingJson?]
    
    public init(parameterName: String) {
        payload = JSON.LinkClick(
            ...
        )
        contexts = [
            JSON.ContextSource(
                ...
            )
        ]
    }
}

to separately generate payload and contexts and assemble them only later when needed.

This allows having access to individual parts of event(payload and contexts), differentiating events with dynamic type casting if needed in rare circumstances and all with an extremely lightweight syntax.
This can be partially replicated with global/static functions, but it will be much more cumbersome and there will be no way to have different types under SelfDescribingJson parent.

@snowplowcla
Copy link

Thanks for your pull request. Is this your first contribution to a Snowplow open source project? Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://docs.snowplowanalytics.com/docs/contributing/contributor-license-agreement/ to learn more and sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.

@snowplowcla snowplowcla added the cla:no [Auto generated] Snowplow Contributor License Agreement has not been signed. label Sep 17, 2024
@TwoDollarsEsq
Copy link
Author

I signed it!

@snowplowcla
Copy link

Confirmed! @TwoDollarsEsq has signed the Contributor License Agreement. Thanks so much.

@snowplowcla snowplowcla added cla:yes [Auto generated] Snowplow Contributor License Agreement has been signed. and removed cla:no [Auto generated] Snowplow Contributor License Agreement has not been signed. labels Sep 17, 2024
This allow inheritance on the client side. This as the behaviour available with Objc version of the SDK and one I could not find any drawback in the current state of the SDK. Being able to inherit allows of use of type's init while preserving SelfDescribingJson identity.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla:yes [Auto generated] Snowplow Contributor License Agreement has been signed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants