Skip to content

SubscriberAttribute: converted into struct#1648

Merged
NachoSoto merged 2 commits into
mainfrom
subscriber-attribute-encodable
Jun 17, 2022
Merged

SubscriberAttribute: converted into struct#1648
NachoSoto merged 2 commits into
mainfrom
subscriber-attribute-encodable

Conversation

@NachoSoto

@NachoSoto NachoSoto commented Jun 2, 2022

Copy link
Copy Markdown
Contributor

Motivation:

Initially I wanted to make SubscriberAttribute.asDictionary work using Codable. However, this isn't the right refactor because we need the actual raw types to be encoded inside UserDefaults.
At least this refactor provides several improvements:

Changes:

  • SubscriberAttribute now has value semantics
  • ⚠️ SubscriberAttribute.isSynced used to be mutable, with reference semantics, which was dangerous
  • SubscriberAttribute: Equatable implementation is now automatic
  • Cleaned up SubscriberAttribute.asDictionary implementation, extracting keys into an enum
  • Moved Dictionary -> SubscriberAttribute creation to the type itself
  • ⚠️ SubscriberAttribute.init(dictionary:) returns an Optional instead of using force-unwrap, avoiding potential crashes
  • Added more serialization / deserialization tests
  • Removed SubscriberAttributesMarshaller and moved method into SubscriberAttribute extension
  • Moved SubscriberAttributeDict into SubscriberAttribute.Dictionary

import Foundation

class SubscriberAttribute {
struct SubscriberAttribute {

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.

👋🏻 Objective-C

@DefaultDecodable.EmptyString
var value: String
@DefaultDecodable.False
var isSynced: Bool

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.

This had mutable reference semantics 🤮

@NachoSoto NachoSoto changed the title [skip ci] [WIP] Converted SubscriberAttribute to Codable [WIP] Converted SubscriberAttribute to Codable Jun 6, 2022
@NachoSoto NachoSoto added the WIP label Jun 8, 2022
@NachoSoto NachoSoto force-pushed the subscriber-attribute-encodable branch 3 times, most recently from 504b93a to 76279b3 Compare June 16, 2022 21:32
@NachoSoto NachoSoto changed the title [WIP] Converted SubscriberAttribute to Codable SubscriberAttribute: converted into struct Jun 16, 2022
@NachoSoto NachoSoto requested a review from a team June 16, 2022 21:33
@NachoSoto NachoSoto removed the WIP label Jun 16, 2022
@NachoSoto NachoSoto marked this pull request as ready for review June 16, 2022 21:33
Comment thread Sources/Caching/DeviceCache.swift Outdated

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.

This is SubscriberAttribute.init?(dictionary:) now.

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.

This was duplicated.

@NachoSoto NachoSoto force-pushed the subscriber-attribute-encodable branch from 76279b3 to 662850f Compare June 16, 2022 21:35
Initially I wanted to make `SubscriberAttribute.asDictionary` work using `Codable`. However, this isn't the right refactor because we need the actual raw types to be encoded inside `UserDefaults`.
At least this refactor provides several improvements:

- `SubscriberAttribute` now has value semantics
- `SubscriberAttribute.isSynced` used to be mutable, with reference semantics, which was dangerous
- `SubscriberAttribute: Equatable` implementation is now automatic
- Cleaned up `SubscriberAttribute.asDictionary` implementation, extracting keys into an `enum`
- Moved `Dictionary` -> `SubscriberAttribute` creation to the type itself
- `SubscriberAttribute.init(dictionary:)` returns an `Optional` instead of using force-unwrap, avoiding potential crashes
- Added more serialization / deserialization tests
- Removed `SubscriberAttributesMarshaller` and moved method into `SubscriberAttribute` extension
- Moved `SubscriberAttributeDict` into `SubscriberAttribute.Dictionary`
@NachoSoto NachoSoto force-pushed the subscriber-attribute-encodable branch from 662850f to a0a0731 Compare June 16, 2022 21:35
expect(self.deviceCache.isOfferingsCacheStale(isAppBackgrounded: true)) == false
}

func testInitWithDictionarySetsRightValues() {

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.

This is tested in SubscriberAttributeTests now since the implementation is there.


let receivedDictionary = subscriberAttribute.asBackendDictionary()
expect(receivedDictionary.keys.count) == 2
func testEncodeAndDecode() throws {

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.

This important new test ensures that encoding + decoding results in the same data.


enum SubscriberAttributesMarshaller {

// fixme: make `SubscriberAttributeDict` `Encodable` instead

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.

This was the goal of this PR, but as I explained in the description it didn't make sense. At least the existing implementation is cleaner now.

@taquitos taquitos left a comment

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.

Great change, only one update, then 🚢🐐

Comment thread Sources/SubscriberAttributes/SubscriberAttribute.swift Outdated
@NachoSoto NachoSoto merged commit a2fc04c into main Jun 17, 2022
@NachoSoto NachoSoto deleted the subscriber-attribute-encodable branch June 17, 2022 17:00
@NachoSoto NachoSoto mentioned this pull request Jun 30, 2022
NachoSoto added a commit that referenced this pull request Jul 4, 2022
### Changes:
* Replaced `CustomerInfo.nonSubscriptionTransactions` with a new non-`StoreTransaction` type (#1733) via NachoSoto (@NachoSoto)
* `Purchases.configure`: added overload taking a `Configuration.Builder` (#1720) via NachoSoto (@NachoSoto)
* Extract Attribution logic out of Purchases (#1693) via Joshua Liebowitz (@taquitos)
* Remove create alias (#1695) via Joshua Liebowitz (@taquitos)

All attribution APIs can now be accessed from `Purchases.shared.attribution`.

### Improvements:
* Improved purchasing logs, added promotional offer information (#1725) via NachoSoto (@NachoSoto)
* `PurchasesOrchestrator`: don't log attribute errors if there are none (#1742) via NachoSoto (@NachoSoto)
* `FatalErrorUtil`: don't override `fatalError` on release builds (#1736) via NachoSoto (@NachoSoto)
* `SKPaymentTransaction`: added more context to warnings about missing properties (#1731) via NachoSoto (@NachoSoto)
* New SwiftUI Purchase Tester example (#1722) via Josh Holtz (@joshdholtz)
* update docs for `showManageSubscriptions` (#1729) via aboedo (@aboedo)
* `PurchasesOrchestrator`: unify finish transactions between SK1 and SK2 (#1704) via NachoSoto (@NachoSoto)
* `SubscriberAttribute`: converted into `struct` (#1648) via NachoSoto (@NachoSoto)
* `CacheFetchPolicy.notStaleCachedOrFetched`: added warning to docstring (#1708) via NachoSoto (@NachoSoto)
* Clear cached offerings and products after Storefront changes (2/4) (#1583) via Juanpe Catalán (@Juanpe)
* `ROT13`: optimized initialization and removed magic numbers (#1702) via NachoSoto (@NachoSoto)

### Fixes:
* `logIn`/`logOut`: sync attributes before aliasing (#1716) via NachoSoto (@NachoSoto)
* `Purchases.customerInfo(fetchPolicy:)`: actually use `fetchPolicy` parameter (#1721) via NachoSoto (@NachoSoto)
* `PurchasesOrchestrator`: fix behavior dealing with `nil` `SKPaymentTransaction.productIdentifier` during purchase (#1680) via NachoSoto (@NachoSoto)
* `PurchasesOrchestrator.handlePurchasedTransaction`: always refresh receipt data (#1703) via NachoSoto (@NachoSoto)
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