tikhop/TPInAppReceipt

Fatal Crash: Unexpectedly found nil while implicitly unwrapping an Optional value

Jerland2 opened this issue · 3 comments

Version: TPInAppReceipt 3.1.0 using SPM
Setup: Testing in sandbox env using IAP configuration file.
Crash: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file TPInAppReceipt/InAppReceipt+ASN1Decodable.swift, line 242

		while !container.isAtEnd
		{
			do
			{
				var attributeContainer = try container.nestedUnkeyedContainer(for: ReceiptAttribute.template) as! ASN1UnkeyedDecodingContainerProtocol
				let type: Int32 = try attributeContainer.decode(Int32.self)
				let _ = try attributeContainer.skip(template: .universal(ASN1Identifier.Tag.integer)) // Consume
				var valueContainer = try attributeContainer.nestedUnkeyedContainer(for: .universal(ASN1Identifier.Tag.octetString)) as! ASN1UnkeyedDecodingContainerProtocol
				//let attribute = try container.decode(ReceiptAttribute.self)
				
				switch type
				{
				case InAppReceiptField.quantity:
					quantity = try valueContainer.decode(Int.self)
				case InAppReceiptField.productIdentifier:
					productIdentifier = try valueContainer.decode(String.self)
				case InAppReceiptField.productType:
					productType = Type(rawValue: try valueContainer.decode(Int32.self)) ?? .unknown
				case InAppReceiptField.transactionIdentifier:
					transactionIdentifier = try valueContainer.decode(String.self)
				case InAppReceiptField.purchaseDate:
					let purchaseDateString = try valueContainer.decode(String.self, template: .universal(ASN1Identifier.Tag.ia5String))
					purchaseDate = purchaseDateString.rfc3339date()!
				case InAppReceiptField.originalTransactionIdentifier:
					originalTransactionIdentifier = try valueContainer.decode(String.self)
				case InAppReceiptField.originalPurchaseDate:
					let originalPurchaseDateString = try valueContainer.decode(String.self, template: .universal(ASN1Identifier.Tag.ia5String))
					originalPurchaseDate = originalPurchaseDateString.rfc3339date()!
				case InAppReceiptField.subscriptionExpirationDate:
					let str = try valueContainer.decode(String.self, template: .universal(ASN1Identifier.Tag.ia5String))
					let subscriptionExpirationDateString = str == "" ? nil : str
					subscriptionExpirationDate = subscriptionExpirationDateString?.rfc3339date()
				case InAppReceiptField.cancellationDate:
					let str = try valueContainer.decode(String.self, template: .universal(ASN1Identifier.Tag.ia5String))
					let cancellationDateString = str == "" ? nil : str
					cancellationDate = cancellationDateString?.rfc3339date()
				case InAppReceiptField.webOrderLineItemID:
					webOrderLineItemID = try valueContainer.decode(Int.self)
				case InAppReceiptField.subscriptionTrialPeriod:
					subscriptionTrialPeriod = (try valueContainer.decode(Int32.self)) != 0
				case InAppReceiptField.subscriptionIntroductoryPricePeriod:
					subscriptionIntroductoryPricePeriod = (try valueContainer.decode(Int32.self)) != 0
				case InAppReceiptField.promotionalOfferIdentifier:
					promotionalOfferIdentifier = try valueContainer.decode(String.self)
				default:
					break
				}
			}
		}
		
		self.originalTransactionIdentifier = originalTransactionIdentifier
		self.productIdentifier = productIdentifier
		self.transactionIdentifier = transactionIdentifier
		self.purchaseDate = purchaseDate
		self.originalPurchaseDate = originalPurchaseDate // FATAL ERROR OCCURS HERE
	}

This causes application to crash on all subsequent runs after purchasing the first IAP. Fatal error commented with "// FATAL ERROR OCCURS HERE" in the above snippet.

Will be rolling back to 3.0.2 until resolved. 3.0.2 does not exhibit this behavior.

Hi @Jerland2,

Thanks for the report, I'm looking into it.

@Jerland2 Confirmed. I will push a fix in a few. Thanks again.

@Jerland2 Just updated cocoapods. Thanks again for the report.