apptentive / apptentive-kit-ios

ApptentiveKit SDK for iOS and iPadOS

Home Page:https://www.apptentive.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Version number not present in Version.plist prevents successful initialization

opened this issue · comments

When installing ApptentiveKit 6.0.2 via Swift Package Manager, calls to Apptentive.shared.register(with:completion:) failed with a 422 client error. The response body to the POST to /conversations endpoint has the message "App release Sdk version is invalid". (see below) Cloning the repo, inserting the actual 6.0.2 version number into Version.plist resolves the issue. I put this fix up in PR#14 but this is probably not the proper fix since the value is expected to be pulled from Version.xcconfig.

It appears that the Resources/Version.plist contains a CFBundleShortVersionString value of $(APPTENTIVE_VERSION) instead of the actual version of the SDK and this value is loaded in Environment.swift in the Environment.sdkVersion lazy var and eventually sent in the POST to the /conversations endpoint.

Error Response:

HTTP/1.1 422 Unprocessable Entity
Server: nginx
Date: Wed, 11 May 2022 01:08:21 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
X-Request-Id: 3172e585-d80d-4af4-9afc-025ecd7c8179
Vary: Origin,Accept-Encoding
Strict-Transport-Security: max-age=31536000
Content-Encoding: gzip

{
  "errors": [
    "App release Sdk version is invalid",
    "App release is invalid"
  ]
}

This 422 was from a Post to the URL with a payload that seems to have a variable interpolation problem see the occurrences of $(APPTENTIVE_VERSION) in the header and two instances in request body for sdk_version field and sdk_distribution_version below (Note: some values elided with xxxxxx):

POST /conversations HTTP/1.1
Host: api.apptentive.com
APPTENTIVE-KEY: xxxxxxxx
Accept: application/json;charset=UTF-8
Accept-Charset: UTF-8
APPTENTIVE-SIGNATURE: xxxxxxx
Accept-Language: en
X-API-Version: 11
Accept-Encoding: gzip, deflate, br
Content-Length: 1075
User-Agent: Apptentive/$(APPTENTIVE_VERSION) (Apple)
Connection: keep-alive
Content-Type: application/json;charset=UTF-8

{
  "person": {
    "custom_data": {}
  },
  "device": {
    "uuid": "27F5BB82-0FEC-4333-AADB-10B0C9A0355C",
    "os_name": "iOS",
    "locale_language_code": "en",
    "integration_config": {},
    "os_build": "21E258",
    "custom_data": {},
    "locale_country_code": "US",
    "utc_offset": -25200,
    "os_version": "15.4",
    "locale_raw": "en_US",
    "hardware": "MacBookPro16,1",
    "content_size_category": "UICTContentSizeCategoryL"
  },
  "app_release": {
    "sdk_version": "$(APPTENTIVE_VERSION)",
    "dt_platform_version": "15.4",
    "dt_platform_build": "19E239",
    "cf_bundle_short_version_string": "8.2.0",
    "sdk_platform": "iOS",
    "cf_bundle_version": "0",
    "sdk_programming_language": "Swift",
    "app_store_receipt": {
      "has_receipt": false
    },
    "dt_xcode_build": "13E500a",
    "dt_xcode": "1331",
    "type": "ios",
    "dt_platform_name": "iphonesimulator",
    "overriding_styles": false,
    "deployment_target": "13.0",
    "dt_sdk_name": "iphonesimulator15.4",
    "debug": true,
    "sdk_author_name": "Apptentive, Inc.",
    "dt_compiler": "com.apple.compilers.llvm.clang.1_0",
    "dt_sdk_build": "19E239",
    "sdk_distribution_version": "$(APPTENTIVE_VERSION)",
    "sdk_distribution": "SPM",
    "cf_bundle_identifier": "xxxxxxxxx"
  }
}

ApptentiveSDKVersion

Is the correct workaround for now to just import into the Xcode project as a framework or cocoa pod so it will pickup the values from Version.xcconfig?

Thanks for the report, and sorry for introducing this bug. We were attempting to reduce the number of places where the version number is copy-pasted, but in retrospect it should have been obvious that this wouldn't work with Swift Package Manager.

In the short run you can point your Swift Package Manager at the contributions branch, which now includes your fix, and we'll get it in our next release as soon as we can.

I've merged this to main and replaced the v6.0.2 tag to point to the new commit, so that folks pulling down this version/package for the first time should be able to avoid this issue.

If you're already seeing this issue you may need to click File > Packages > Reset Package Cache in Xcode.

Thanks for taking care of this so quickly! I wonder if you could solve the problem of having to cut/paste for every release with something like SE-0303 Package Manager Extensible Build Tools.

...or alternately update the code below in Environment.swift to read the version string directly out of Version.xcconfig instead of Version.plist

    lazy var sdkVersion: Version = {
        // First look for Version.plist, which is a workaround for Swift Package Manager.
        if let url = Bundle.module.url(forResource: "Version", withExtension: "plist"),
            let data = try? Data(contentsOf: url),
            let infoDictionary = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any],
            let versionString = infoDictionary["CFBundleShortVersionString"] as? String
        {
            return Version(string: versionString)
        }

Thanks, @provBarryTolnas. Will take a look at this with the engineering team. Always appreciate the feedback!

For the time being we're going to make sure manually updating the version when we do a release. I'm going to go ahead and close this since the immediate bug seems to resolved.