diff --git a/examples/gen-ios/objectivec/TypewriterExample/Analytics/SEGKicksAppAnalytics.h b/examples/gen-ios/objectivec/TypewriterExample/Analytics/SEGKicksAppAnalytics.h index 124cb62a..ca64b4d7 100644 --- a/examples/gen-ios/objectivec/TypewriterExample/Analytics/SEGKicksAppAnalytics.h +++ b/examples/gen-ios/objectivec/TypewriterExample/Analytics/SEGKicksAppAnalytics.h @@ -25,22 +25,22 @@ NS_ASSUME_NONNULL_BEGIN /// Currency code associated with the transaction @property (nonatomic, nullable, copy) NSString *currency; /// Total discount associated with the transaction -@property (nonatomic, nullable, assign) NSNumber *discount; +@property (nonatomic, nullable, copy) NSNumber *discount; /// Order/transaction ID @property (nonatomic, copy) NSString *orderID; /// Products in the order @property (nonatomic, nullable, copy) NSArray *products; /// Revenue associated with the transaction (excluding shipping and tax) -@property (nonatomic, nullable, assign) NSNumber *revenue; +@property (nonatomic, nullable, copy) NSNumber *revenue; /// Shipping cost associated with the transaction -@property (nonatomic, nullable, assign) NSNumber *shipping; +@property (nonatomic, nullable, copy) NSNumber *shipping; /// Total tax associated with the transaction -@property (nonatomic, nullable, assign) NSNumber *tax; +@property (nonatomic, nullable, copy) NSNumber *tax; /// Revenue with discounts and coupons added in. Note that our Google Analytics Ecommerce /// destination accepts total or revenue, but not both. For better flexibility and total /// control over tracking, we let you decide how to calculate how coupons and discounts are /// applied -@property (nonatomic, nullable, assign) NSNumber *total; +@property (nonatomic, nullable, copy) NSNumber *total; @end typedef void (^ SEGOrderCompletedBuilderBlock)(SEGOrderCompletedBuilder *); @@ -55,22 +55,22 @@ typedef void (^ SEGOrderCompletedBuilderBlock)(SEGOrderCompletedBuilder *); /// Currency code associated with the transaction @property (nonatomic, nullable, copy) NSString *currency; /// Total discount associated with the transaction -@property (nonatomic, nullable, assign) NSNumber *discount; +@property (nonatomic, nullable, copy) NSNumber *discount; /// Order/transaction ID @property (nonatomic, copy) NSString *orderID; /// Products in the order @property (nonatomic, nullable, copy) NSArray *products; /// Revenue associated with the transaction (excluding shipping and tax) -@property (nonatomic, nullable, assign) NSNumber *revenue; +@property (nonatomic, nullable, copy) NSNumber *revenue; /// Shipping cost associated with the transaction -@property (nonatomic, nullable, assign) NSNumber *shipping; +@property (nonatomic, nullable, copy) NSNumber *shipping; /// Total tax associated with the transaction -@property (nonatomic, nullable, assign) NSNumber *tax; +@property (nonatomic, nullable, copy) NSNumber *tax; /// Revenue with discounts and coupons added in. Note that our Google Analytics Ecommerce /// destination accepts total or revenue, but not both. For better flexibility and total /// control over tracking, we let you decide how to calculate how coupons and discounts are /// applied -@property (nonatomic, nullable, assign) NSNumber *total; +@property (nonatomic, nullable, copy) NSNumber *total; @end @interface SEGProduct : NSObject @@ -85,13 +85,13 @@ typedef void (^ SEGOrderCompletedBuilderBlock)(SEGOrderCompletedBuilder *); /// Name of the product being viewed @property (nonatomic, nullable, copy) NSString *name; /// Position in the product list (ex. 3) -@property (nonatomic, nullable, assign) NSNumber *position; +@property (nonatomic, nullable, copy) NSNumber *position; /// Price of the product being viewed -@property (nonatomic, nullable, assign) NSNumber *price; +@property (nonatomic, nullable, copy) NSNumber *price; /// Database id of the product being viewed @property (nonatomic, nullable, copy) NSString *productID; /// Quantity of a product -@property (nonatomic, nullable, assign) NSNumber *quantity; +@property (nonatomic, nullable, copy) NSNumber *quantity; /// Sku of the product being viewed @property (nonatomic, nullable, copy) NSString *sku; /// URL of the product page @@ -114,13 +114,13 @@ typedef void (^ SEGProductBuilderBlock)(SEGProductBuilder *); /// Name of the product being viewed @property (nonatomic, nullable, copy) NSString *name; /// Position in the product list (ex. 3) -@property (nonatomic, nullable, assign) NSNumber *position; +@property (nonatomic, nullable, copy) NSNumber *position; /// Price of the product being viewed -@property (nonatomic, nullable, assign) NSNumber *price; +@property (nonatomic, nullable, copy) NSNumber *price; /// Database id of the product being viewed @property (nonatomic, nullable, copy) NSString *productID; /// Quantity of a product -@property (nonatomic, nullable, assign) NSNumber *quantity; +@property (nonatomic, nullable, copy) NSNumber *quantity; /// Sku of the product being viewed @property (nonatomic, nullable, copy) NSString *sku; /// URL of the product page diff --git a/package.json b/package.json index 8bf1ec44..0d00ada1 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "scripts": { "start": "node ./dist/src/index.js", "test": "jest", - "update-snapshots": "jest -u", "watch": "tsc -w", "build": "rm -rf dist && tsc", "prepare": "yarn run build", diff --git a/src/commands/gen-ios.ts b/src/commands/gen-ios.ts index caaa7216..2091bbbc 100644 --- a/src/commands/gen-ios.ts +++ b/src/commands/gen-ios.ts @@ -9,11 +9,12 @@ import { Name, Sourcelike, Type, - ObjectType + ObjectType, + matchType } from 'quicktype-core' import { stringEscape } from 'quicktype-core/dist/support/Strings' import { OptionValues, StringOption } from 'quicktype-core/dist/RendererOptions' -import { objcOptions } from 'quicktype-core/dist/language/Objective-C' +import { objcOptions, MemoryAttribute } from 'quicktype-core/dist/language/Objective-C' import { getTypedTrackHandler, @@ -564,9 +565,35 @@ class AnalyticsObjectiveCWrapperRenderer extends ObjectiveCRenderer { }) } + /** + * Always used the boxed types, because of a potential upstream bu with nullable values + * in QuickType. We need to use a boxed type if we make attach the `nullable` property modifier. + */ protected objcType(t: Type, _: boolean): [Sourcelike, string] { return super.objcType(t, true) } + + /** + * Override memoryAttribute in order to replace assign with copy for numeric types. + * + * Defer to QuickType for all other types. + */ + protected memoryAttribute(t: Type, isNullable: boolean): MemoryAttribute { + return matchType( + t, + anyType => super.memoryAttribute(t, isNullable), + nullType => super.memoryAttribute(t, isNullable), + boolType => super.memoryAttribute(t, isNullable), + integerType => (isNullable ? 'strong' : 'copy'), + doubleType => (isNullable ? 'strong' : 'copy'), + stringType => super.memoryAttribute(t, isNullable), + arrayType => super.memoryAttribute(t, isNullable), + classType => super.memoryAttribute(t, isNullable), + mapType => super.memoryAttribute(t, isNullable), + enumType => super.memoryAttribute(t, isNullable), + unionType => super.memoryAttribute(t, isNullable) + ) + } } export async function genObjC(events: TrackedEvent[], { trackingPlan, classPrefix }: Params) { diff --git a/tests/commands/gen-ios/__snapshots__/SEGTestTrackingPlanAnalytics.h b/tests/commands/gen-ios/__snapshots__/SEGTestTrackingPlanAnalytics.h index 8bc4f6f3..abc6a731 100644 --- a/tests/commands/gen-ios/__snapshots__/SEGTestTrackingPlanAnalytics.h +++ b/tests/commands/gen-ios/__snapshots__/SEGTestTrackingPlanAnalytics.h @@ -53,11 +53,11 @@ typedef void (^ SEGThe42_TerribleEventName3BuilderBlock)(SEGThe42_TerribleEventN /// Optional boolean property @property (nonatomic, nullable, assign) NSNumber *isOptionalBoolean; /// Optional integer property -@property (nonatomic, nullable, assign) NSNumber *optionalInt; -@property (nonatomic, nullable, copy) NSString *optionalNullableString; +@property (nonatomic, nullable, copy) NSNumber *optionalInt; +@property (nonatomic, nullable, copy) NSString *optionalNullableString; /// Optional number property -@property (nonatomic, nullable, assign) NSNumber *optionalNumber; -@property (nonatomic, nullable, copy) id optionalNumberOrString; +@property (nonatomic, nullable, copy) NSNumber *optionalNumber; +@property (nonatomic, nullable, copy) id optionalNumberOrString; /// Optional object property @property (nonatomic, nullable, strong) SEGOptionalObject *optionalObject; /// Optional object (empty) property @@ -75,11 +75,11 @@ typedef void (^ SEGThe42_TerribleEventName3BuilderBlock)(SEGThe42_TerribleEventN /// Required boolean property @property (nonatomic, assign) NSNumber *isRequiredBoolean; /// Required integer property -@property (nonatomic, assign) NSNumber *requiredInt; -@property (nonatomic, copy) NSString *requiredNullableString; +@property (nonatomic, copy) NSNumber *requiredInt; +@property (nonatomic, copy) NSString *requiredNullableString; /// Required number property -@property (nonatomic, assign) NSNumber *requiredNumber; -@property (nonatomic, copy) id requiredNumberOrString; +@property (nonatomic, copy) NSNumber *requiredNumber; +@property (nonatomic, copy) id requiredNumberOrString; /// Required object property @property (nonatomic, strong) SEGRequiredObject *requiredObject; /// Required object (empty) property @@ -102,11 +102,11 @@ typedef void (^ SEGExampleEventBuilderBlock)(SEGExampleEventBuilder *); /// Optional boolean property @property (nonatomic, nullable, assign) NSNumber *isOptionalBoolean; /// Optional integer property -@property (nonatomic, nullable, assign) NSNumber *optionalInt; -@property (nonatomic, nullable, copy) NSString *optionalNullableString; +@property (nonatomic, nullable, copy) NSNumber *optionalInt; +@property (nonatomic, nullable, copy) NSString *optionalNullableString; /// Optional number property -@property (nonatomic, nullable, assign) NSNumber *optionalNumber; -@property (nonatomic, nullable, copy) id optionalNumberOrString; +@property (nonatomic, nullable, copy) NSNumber *optionalNumber; +@property (nonatomic, nullable, copy) id optionalNumberOrString; /// Optional object property @property (nonatomic, nullable, strong) SEGOptionalObject *optionalObject; /// Optional object (empty) property @@ -124,11 +124,11 @@ typedef void (^ SEGExampleEventBuilderBlock)(SEGExampleEventBuilder *); /// Required boolean property @property (nonatomic, assign) NSNumber *isRequiredBoolean; /// Required integer property -@property (nonatomic, assign) NSNumber *requiredInt; -@property (nonatomic, copy) NSString *requiredNullableString; +@property (nonatomic, copy) NSNumber *requiredInt; +@property (nonatomic, copy) NSString *requiredNullableString; /// Required number property -@property (nonatomic, assign) NSNumber *requiredNumber; -@property (nonatomic, copy) id requiredNumberOrString; +@property (nonatomic, copy) NSNumber *requiredNumber; +@property (nonatomic, copy) id requiredNumberOrString; /// Required object property @property (nonatomic, strong) SEGRequiredObject *requiredObject; /// Required object (empty) property diff --git a/yarn.lock b/yarn.lock index fcb4f384..f15eb209 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4056,9 +4056,9 @@ js-tokens@^3.0.2: integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== dependencies: argparse "^1.0.7" esprima "^4.0.0"