Giter Site home page Giter Site logo

adaptyteam / adaptysdk-ios Goto Github PK

View Code? Open in Web Editor NEW
347.0 17.0 39.0 14.12 MB

iOS SDK for growing mobile in-app purchases

Home Page: https://docs.adapty.io/docs/quickstart

License: MIT License

Ruby 0.22% Swift 99.72% Objective-C 0.05%
ios purchases iap sdk entitlements in-app-purchase storekit receipt-validation subscription macos

adaptysdk-ios's People

Contributors

akyashkin avatar another1dd avatar camji55 avatar cyberdev-ios avatar dardary avatar ditansu avatar elena-gordienko avatar guiyec avatar ihityouback avatar iwitaly avatar kpotehin avatar larryonoff avatar monyschuk avatar nikans avatar rudrankriyam avatar skifcha avatar valyano avatar vpsyukalovzuzex avatar x401om avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adaptysdk-ios's Issues

Callbacks called twice

Hi, I've noticed that all callbacks in you SDK called twice with different 'state'. But in some cases it called only once, it makes usage harder in some cases, for ex. DispatchGroups. Maybe I can specify somewhere to call callback only once for state .synced, or specify behaviour like synced if can or cached if not.

Crashes with version 1.17.3

As with 1.17.2 we can reliably get a crash on backgrounding of the app when the Adapty SDK is active within the app.

It appears to the the same as this

Thread 0 - (TH_STATE_WAITING)
0  BoardServices    -[BSServiceConnectionEndpointMonitor dealloc]
1  UIKitCore        -[UIApplication .cxx_destruct]
2  libobjc.A.dylib  object_cxxDestructFromClass(objc_object*, objc_class*)
3  libobjc.A.dylib  _objc_destructInstance
4  libobjc.A.dylib  __objc_rootDealloc
5  UIKitCore        -[UIResponder dealloc]
6  UIKitCore        -[UIApplication dealloc]
7  Foundation       -[_NSThreadPerformInfo dealloc]
8  Foundation       ___NSThreadPerformPerform
9  CoreFoundation   ___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
10 CoreFoundation   ___CFRunLoopDoSource0
11 CoreFoundation   ___CFRunLoopDoSources0
12 CoreFoundation   ___CFRunLoopRun
13 CoreFoundation   _CFRunLoopRunSpecific
14 GraphicsServices _GSEventRunModal
15 UIKitCore        -[UIApplication _run]
16 UIKitCore        _UIApplicationMain
17 AppName          main (AppDelegate.swift:28:7)
18 dyld             start

Implement support for iOS App Extensions

Adapty uses UIApplication.shared under the hood. So it's impossible to use Adapty iOS SDK in App Extensions.

Please implement support for iOS App Extensions.

Support Xcode simulator

After completing the purchase using the emulator, it prompts an error:

Error Domain=com.adapty.AdaptySDK Code=400 "Status: APPLE_RECEIPT_VALIDATION_ERROR. Details: 21002" UserInfo={NSLocalizedDescription=Status: APPLE_RECEIPT_VALIDATION_ERROR. Details: 21002}

Support for iOS App Extensions

Currently, subscription data cannot be shared between the main app and extensions because internally you store profile data in the UserDefaults.standard. As a result, each extension must individually fetch subscription status.

To address this issue, you can include a userDefaults parameter in the Adapty.activate method, allowing the profile data to be stored in an app group.

Adapty.activate(
  "adapty-api-key",
  customerUserId: "user-id",
  userDefaults: .init(suiteName: "group.com.example")
)

Issue with getting PurchaserInfo

When I try

Adapty.getPurchaserInfo(forceUpdate: true) { purchaserInfo, error in

I keep getting this error

Error Domain=com.adapty.AdaptySDK Code=2007 "Missing some of the required params: `JSON response - attributes`" UserInfo={NSLocalizedDescription=Missing some of the required params: `JSON response - attributes`}

Repeated calls to api/v1/sdk/events/blacklist when internet connection offline

When a users internet connection is offline Adapty SDK is making repeated calls to the https://api.adapty.io/api/v1/sdk/events/blacklist/ endpoint on launch, causing EventManager.trackEvent to peg the CPU.

We initialise Adapty in our UIApplicationDelegate's func application(_ application:, didFinishLaunchingWithOptions launchOptions:) like so:

Adapty.activate("X", observerMode: true)

This is the only call made to Adapty before the requests start. To replicate this you can follow the following steps:

  1. Turn on Airplane mode
  2. Start an application that makes use of the Adapty iOS SDK

Ideally a failure to fetch the events/blacklist would result in an exponential backoff, rather than repeated re-attempts.

logs
Task <AB7BCD97-98C1-45DB-9F83-88EDF1382F13>.<4920> finished with error [-1009] 
Error Domain=NSURLErrorDomain Code=-1009 "The internet connection appears to be offline."
 UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x280b573f0 
 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_kCFStreamErrorDomainKey=1, 
 _kCFStreamErrorCodeKey=50, _NSURLErrorNWResolutionReportKey=Resolved 0 endpoints in 0ms 
 using unknown from cache, _NSURLErrorNWPathKey=unsatisfied (No network route)}}, 
 _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <AB7BCD97-98C1-45DB-9F83-88EDF1382F13>.<4920>,
 _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <AB7BCD97-98C1-45DB-9F83-88EDF1382F13>.<4920>"
), NSLocalizedDescription=The internet connection appears to be offline., 
NSErrorFailingURLStringKey=https://api.adapty.io/api/v1/sdk/events/blacklist/, 
NSErrorFailingURLKey=https://api.adapty.io/api/v1/sdk/events/blacklist/, _kCFStreamErrorDomainKey=1}
Connection 4943: received failure notification
Connection 4943: failed to connect 1:50, reason -1
Connection 4943: encountered error(1:50)

Crash on SKQueueManager.receivedFailedTransaction

Operating System: iOS 17.2.1
Device: Phone 15 Pro Max
SDK Version: Adapty 2.7.0

Crashed: Fatal Exception: NSRangeException
[__NSArrayM removeObjectsInRange:]: range {0, 1} extends beyond bounds for empty array

Fatal Exception: NSRangeException
0  CoreFoundation                 0xec69c __exceptionPreprocess
1  libobjc.A.dylib                0x2bc80 objc_exception_throw
2  CoreFoundation                 0x39228 -[__NSArrayM removeObjectsInRange:]
3  StoreKit                       0x33808 -[SKPaymentQueue _removeLocalTransaction:]
4  StoreKit                       0x2db58 -[SKPaymentQueue finishTransaction:]
5  Adapty                         0xea028 closure #1 in SKQueueManager.receivedFailedTransaction(_:) + 40 (SKQueueManager+MakePurchase.swift:40)
6  Adapty                         0x12ab0 thunk for @escaping @callee_guaranteed @Sendable () -> () (<compiler-generated>)
7  libdispatch.dylib              0x26a8 _dispatch_call_block_and_release
8  libdispatch.dylib              0x4300 _dispatch_client_callout
9  libdispatch.dylib              0xb894 _dispatch_lane_serial_drain
10 libdispatch.dylib              0xc3c4 _dispatch_lane_invoke
11 libdispatch.dylib              0x17004 _dispatch_root_queue_drain_deferred_wlh
12 libdispatch.dylib              0x16878 _dispatch_workloop_worker_thread
13 libsystem_pthread.dylib        0x1964 _pthread_wqthread
14 libsystem_pthread.dylib        0x1a04 start_wqthread

This crash occurred for App Store users.

Crash happened after successful purchase in ProfileStorage+UserDefaults.swift

Model:iPhone 6s
RAM free: 167.7 MB
Disk free: 2 GB
Operating System Version:15.7.8
Orientation:Portrait
Jailbroken:No

Stack trace:

Fatal Exception: NSInternalInconsistencyException
0  CoreFoundation                 0x92c60 (Missing UUID 717d70c93b8e3abcae16050588fc3ee8)
1  libobjc.A.dylib                0x14ee4 objc_exception_throw
2  Foundation                     0x124c80 (Missing UUID c3a840e10d1132a3937f7f668ffb13f0)
3  UIKitCore                      0x2c6320 (Missing UUID 36ae0870fed03b878a60bb2ee5192744)
4  UIKitCore                      0x4fc338 (Missing UUID 36ae0870fed03b878a60bb2ee5192744)
5  UIKitCore                      0x301490 (Missing UUID 36ae0870fed03b878a60bb2ee5192744)
6  SwiftUI                        0xd6860 (Missing UUID 0ced97dbca5433979454eca652de731b)
7  SwiftUI                        0xe2b1c (Missing UUID 0ced97dbca5433979454eca652de731b)
8  SwiftUI                        0x5c2fc (Missing UUID 0ced97dbca5433979454eca652de731b)
9  SwiftUI                        0x8b87c (Missing UUID 0ced97dbca5433979454eca652de731b)
10 AttributeGraph                 0x4114 AG::Graph::UpdateStack::update()
11 AttributeGraph                 0x3880 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int)
12 AttributeGraph                 0x2794 AG::Subgraph::update(unsigned int)
13 SwiftUI                        0x15324 (Missing UUID 0ced97dbca5433979454eca652de731b)
14 SwiftUI                        0x44afc (Missing UUID 0ced97dbca5433979454eca652de731b)
15 SwiftUI                        0x4a190 (Missing UUID 0ced97dbca5433979454eca652de731b)
16 SwiftUI                        0x1bf74 (Missing UUID 0ced97dbca5433979454eca652de731b)
17 SwiftUI                        0x181f80 (Missing UUID 0ced97dbca5433979454eca652de731b)
18 SwiftUI                        0x1cb84 (Missing UUID 0ced97dbca5433979454eca652de731b)
19 Combine                        0xaa60 ObservableObjectPublisher.Inner.send()
20 Combine                        0x1c780 ObservableObjectPublisher.send()
21 SwiftUI                        0xb2f660 (Missing UUID 0ced97dbca5433979454eca652de731b)
22 SwiftUI                        0xb2f944 (Missing UUID 0ced97dbca5433979454eca652de731b)
23 SwiftUI                        0xb2ff08 (Missing UUID 0ced97dbca5433979454eca652de731b)
24 SwiftUI                        0xb2ffb8 (Missing UUID 0ced97dbca5433979454eca652de731b)
25 CoreFoundation                 0x2920c (Missing UUID 717d70c93b8e3abcae16050588fc3ee8)
26 CoreFoundation                 0xbe830 (Missing UUID 717d70c93b8e3abcae16050588fc3ee8)
27 CoreFoundation                 0x93b48 (Missing UUID 717d70c93b8e3abcae16050588fc3ee8)
28 CoreFoundation                 0x3dfa0 (Missing UUID 717d70c93b8e3abcae16050588fc3ee8)
29 Foundation                     0x1a00c (Missing UUID c3a840e10d1132a3937f7f668ffb13f0)
30 XXXXXX                       0x2e2e60 NSUserDefaults.setSyncedBundleReceipt(_:) + 55 (ProfileStorage+UserDefaults.swift:55)
31 XXXXXX                       0x2e3854 protocol witness for ProfileStorage.setSyncedBundleReceipt(_:) in conformance NSUserDefaults (<compiler-generated>)
32 XXXXXX                       0x1fc6dc Adapty.saveValidateReceiptResponse(profile:) + 26 (Adapty+PurchaseValidator.swift:26)
33 XXXXXX                       0x1fc344 specialized Result.map<A>(_:) + 18 (Adapty+PurchaseValidator.swift:18)
34 XXXXXX                       0x1fc5d8 closure #1 in Adapty.validateReceipt(refreshIfEmpty:_:) + 17 (Adapty+PurchaseValidator.swift:17)
35 XXXXXX                       0x2f9080 partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<VH<AdaptyProfile>, AdaptyError>) -> () (<compiler-generated>)
36 XXXXXX                       0x2f68a4 completedValidate #1 (_:) in SKReceiptManager.validateReceipt(refreshIfEmpty:_:) + 63 (SKReceiptManager.swift:63)
37 XXXXXX                       0x2665c8 closure #1 in HTTPSession._performValidateReceiptRequest(_:_:_:_:) + 81 (ValidateReceiptRequest.swift:81)
38 XXXXXX                       0x266694 specialized closure #1 in HTTPSession.perform<A>(_:logName:logStamp:logParams:_:) + 23 (HTTPSession+logSystemEvent.swift:23)
39 XXXXXX                       0x2c9cbc specialized closure #1 in closure #3 in HTTPSession.perform<A, B>(_:queue:decoder:logStamp:_:)
40 XXXXXX                       0x2cc89c partial apply for specialized closure #1 in closure #3 in HTTPSession.perform<A, B>(_:queue:decoder:logStamp:_:)
41 XXXXXX                       0x1ff634 thunk for @escaping @callee_guaranteed @Sendable () -> () (<compiler-generated>)
42 libdispatch.dylib              0x63094 _dispatch_call_block_and_release
43 libdispatch.dylib              0x64094 _dispatch_client_callout
44 libdispatch.dylib              0xa73c _dispatch_lane_serial_drain$VARIANT$mp
45 libdispatch.dylib              0xb1f4 _dispatch_lane_invoke$VARIANT$mp
46 libdispatch.dylib              0x14ec8 _dispatch_workloop_worker_thread
47 libsystem_pthread.dylib        0x1e00 (Missing UUID 309207e069d9317d86ae3a7ca0adc5d1)
48 libsystem_pthread.dylib        0x192c (Missing UUID 309207e069d9317d86ae3a7ca0adc5d1)

Crashed: com.apple.main-thread

Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_PROTECTION_FAILURE 0x000000016ef8bfb0

StackTrace:
Crashed: com.apple.main-thread
0 Adapty 0x13d54 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 4
1 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
2 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
3 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
4 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
5 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
6 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
7 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
8 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
9 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
10 Adapty 0x13db8 $s6Adapty14RequestManagerC07performB033_DD8AA5940EB4E04AC23940BE2B9D6500LL_6router10completionSo20NSURLSessionDataTaskCSg10Foundation10URLRequestV_AA6RouterOSgys6ResultOyxAA0A5ErrorCG_So17NSHTTPURLResponseCSgtctAA11JSONCodableRzlFyAK0P0VSg_So13NSURLResponseCSgs0V0_pSgtcfU_yycfU_yAU_AXtcfU_AA18PurchaserInfoModelC_Tg5 + 104
11 Adapty 0x19e40 $s6Adapty14RequestManagerC12handleResult33_DD8AA5940EB4E04AC23940BE2B9D6500LL4task6result8response10completionyAA15SessionDataTaskAELLC_s0E0OyxAA0A5ErrorCGSo17NSHTTPURLResponseCSgyAP_AStctAA11JSONCodableRzlFyycfU0_AA10PromoModelC_Tg5 + 68
12 Adapty 0x61b0 $sIeg_IeyB_TR + 20
13 libdispatch.dylib 0x602b0 dispatch_call_block_and_release + 24
14 libdispatch.dylib 0x61298 dispatch_client_callout + 16
15 libdispatch.dylib 0x43430 dispatch_main_queue_callback_4CF$VARIANT$armv81 + 872
16 CoreFoundation 0x9a298 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 12
17 CoreFoundation 0x946f8 __CFRunLoopRun + 2528
18 CoreFoundation 0x937d0 CFRunLoopRunSpecific + 572
19 GraphicsServices 0x3570 GSEventRunModal + 160
20 UIKitCore 0xb302d0 -[UIApplication run] + 1052
21 UIKitCore 0xb3584c UIApplicationMain + 164
22 libswiftUIKit.dylib 0x1387c UIApplicationMain(
:
:
:
:) + 100
23 Runner 0x6f04 main + 4372066052 (PurchaseCompleted.swift:4372066052)
24 libdyld.dylib

Keys:
flutter_error_exception
Get purchaser info error: AdaptyError (code -1020) A data connection is not currently allowed.

flutter_error_reason
thrown Get purchaser info error: AdaptyError (code -1020) A data connection is not currently allowed.. Error thrown Adapty.

Locale
en_US

Please remove 'dummy' profiles

I am frustrated that dummy profiles are created when users anonymously log in to the app. I have tried to circumvent this by only calling Adapty.activate() during the login process, but it would be great if these dummy profiles were hidden from the dashboard, or there were a way to remove them all together.

Example code is old version

Hi,

This version has sample with version 1.17.7. But your stable version is 2.0.0. Can you share the sample code for the new version?

Crash on Adapty.SDK.SendEvents Thread

Operating System: iOS 16.0.0
Device: iPhone 14 Pro
SDK Version: Adapty 2.6.2

Crashed: Adapty.SDK.SendEvents
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000000

Crashed: Adapty.SDK.SendEvents
0  libswiftCore.dylib             0x41645c swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::incrementSlow(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 60
1  libswiftCore.dylib             0x3d8f00 swift_retain + 124
2  libswiftCore.dylib             0x3d8f00 swift_retain + 124
3  libswiftCore.dylib             0x41eadc swift_bridgeObjectRetain + 52
4  Adapty                         0x7db9c closure #1 in EventsManager.trackEvent(_:completion:) + 68 (EventsManager.swift:68)
5  Adapty                         0x11e0c thunk for @escaping @callee_guaranteed @Sendable () -> () + 28 (<compiler-generated>:28)
6  libdispatch.dylib              0x24b4 _dispatch_call_block_and_release + 32
7  libdispatch.dylib              0x3fdc _dispatch_client_callout + 20
8  libdispatch.dylib              0xb694 _dispatch_lane_serial_drain + 672
9  libdispatch.dylib              0xc1e0 _dispatch_lane_invoke + 384
10 libdispatch.dylib              0x16e10 _dispatch_workloop_worker_thread + 652
11 libsystem_pthread.dylib        0xdf8 _pthread_wqthread + 288
12 libsystem_pthread.dylib        0xb98 start_wqthread + 8

This crash occurred online, albeit only one. Hope the above information can help

Cannot Mock PaywallModel

Hi,

I'm trying to mock PaywallModel so I can test the creation of Paywalls before submitting my IAP for review.

I looked at ModelsTest in the example project and created this similiar function:

    func getMockPaywall() -> PaywallModel?{
        
        guard let url = Bundle.main.url(forResource: "Paywall", withExtension: "json") else {
            print("Missing file: Paywall.json")
            return nil
        }
        do{
            let data = try Data(contentsOf: url)
            let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
            let paywall = try PaywallModel(json: attributes(from: json))

            return paywall
        }
        catch{
            return nil
        }
        
        return nil
     
    }
     private func attributes(from params: Parameters) -> Parameters {
        return ["attributes": params]
    }

For some reason, the compiler seems to think I'm using the wrong initializer.
I thought this was a conflict specific to my project but the same error appears when I create a clean project with only Adapty.
Screen Shot 2022-05-03 at 6 28 30 PM

I'm using version 1.17.0, Installed with SPM, on SwiftUI if that makes a difference.

Please help ๐Ÿ™

Example does not work properly

ld: in /Pods/AppsFlyerFramework/iOS/AppsFlyerLib.framework/AppsFlyerLib(AppsFlyerHTTPClient.o), building for iOS /Simulator, but linking in object file built for iOS, file '/Pods/AppsFlyerFramework/iOS/AppsFlyerLib.framework/AppsFlyerLib' for architecture arm64

Mac mini (M1, 2020)

Intermittent crash in Adapty.activate(_:observerMode:customerUserId:enableUsageLogs:storeKit2Usage:dispatchQueue:_:)

We're seeing an intermittent crash in our production environment that seems to point to Adapty.activate(_:observerMode:customerUserId:enableUsageLogs:storeKit2Usage:dispatchQueue:_:) (Adapty 2.6.2)

The call to Adapty.activate on our side is made from application(_:didFinishLaunchingWithOptions:) and looks like this:

Adapty.activate("public_live_XXX", observerMode: true)

Attached are two of the latest stacktraces we've received:

CrashReporter Key:  e5f302d9fab07157daf55a18f344fc7ebea95dc4
Hardware Model:     iPhone14,2
Process:            X
Identifier:         X
Version:            14.13.0
Role:               Foreground
OS Version:         iOS 16.6


SIGABRT: 

0  libsystem_kernel.dylib +0x7578  ___pthread_kill
1  libsystem_pthread.dylib +0x7114 _pthread_kill
2  libsystem_c.dylib +0x1d174      _abort
3  libswiftCore.dylib +0x3b8b94    swift::fatalErrorv(unsigned int, char const*, char*)
4  libswiftCore.dylib +0x3b8bb4    swift::fatalError(unsigned int, char const*, ...)
5  libswiftCore.dylib +0x3bd7c4    _swift_deallocClassInstance
6  libswiftCore.dylib +0x3bd614    __swift_release_dealloc
7  libswiftCore.dylib +0x3be438    bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int)
8  X +0x51c0b0          closure #1 in static Adapty.activate(_:observerMode:customerUserId:enableUsageLogs:storeKit2Usage:dispatchQueue:_:) (<compiler-generated>)
9  X +0x52674c          partial apply for closure #1 in static Adapty.activate(_:observerMode:customerUserId:enableUsageLogs:storeKit2Usage:dispatchQueue:_:) (<compiler-generated>)
10 X +0x4f96a8          closure #1 in static Adapty.async(_:group:qos:flags:logName:logParams:function:execute:) (Adapty+AsyncHelpers.swift:31:13)
11 X +0x526b3c          partial apply for closure #1 in static Adapty.async(_:group:qos:flags:logName:logParams:function:execute:) (<compiler-generated>)
12 X +0x516418          thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
13 libdispatch.dylib +0x231c       __dispatch_call_block_and_release
14 libdispatch.dylib +0x3ea8       __dispatch_client_callout
15 libdispatch.dylib +0xb530       __dispatch_lane_serial_drain
16 libdispatch.dylib +0xc0a0       __dispatch_lane_invoke
17 libdispatch.dylib +0x16cd8      __dispatch_workloop_worker_thread
18 libsystem_pthread.dylib +0xdd8  __pthread_wqthread
CrashReporter Key:  af3c552ff8ecf820a11da09d20a826d54d0ac264
Hardware Model:     iPhone13,3
Process:            X
Identifier:         X
Version:            14.13.0
Role:               Foreground
OS Version:         iOS 16.5.1


SIGABRT: 

0  libsystem_kernel.dylib +0x7558  ___pthread_kill
1  libsystem_pthread.dylib +0x7114 _pthread_kill
2  libsystem_c.dylib +0x1d174      _abort
3  libswiftCore.dylib +0x3b8ba4    swift::fatalErrorv(unsigned int, char const*, char*)
4  libswiftCore.dylib +0x3b8bc4    swift::fatalError(unsigned int, char const*, ...)
5  libswiftCore.dylib +0x3bd7d4    _swift_deallocClassInstance
6  libswiftCore.dylib +0x3bd624    __swift_release_dealloc
7  libswiftCore.dylib +0x3be448    bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int)
8  X +0x51c0b0          closure #1 in static Adapty.activate(_:observerMode:customerUserId:enableUsageLogs:storeKit2Usage:dispatchQueue:_:) (<compiler-generated>)
9  X +0x52674c          partial apply for closure #1 in static Adapty.activate(_:observerMode:customerUserId:enableUsageLogs:storeKit2Usage:dispatchQueue:_:) (<compiler-generated>)
10 X +0x4f96a8          closure #1 in static Adapty.async(_:group:qos:flags:logName:logParams:function:execute:) (Adapty+AsyncHelpers.swift:31:13)
11 X +0x526b3c          partial apply for closure #1 in static Adapty.async(_:group:qos:flags:logName:logParams:function:execute:) (<compiler-generated>)
12 X +0x516418          thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
13 libdispatch.dylib +0x231c       __dispatch_call_block_and_release
14 libdispatch.dylib +0x3ea8       __dispatch_client_callout
15 libdispatch.dylib +0xb530       __dispatch_lane_serial_drain
16 libdispatch.dylib +0xc0a0       __dispatch_lane_invoke
17 libdispatch.dylib +0x16cd8      __dispatch_workloop_worker_thread
18 libsystem_pthread.dylib +0xdd8  __pthread_wqthread

Add VisionOS support

Currently, it is not possible to use the Adapty SDK for the VisionOS platform and Xcode 15.2

Screenshot 2024-02-05 at 14 16 10

SPM doesn't support two numbers versioning

Hello,

Could you please make update in naming of versions.

It looks that SPM doesn't support two number versions, e.g. "1.14", "1.15". So it always should have three numbers, e.g. "1.14.0", "1.15.0".

Please see the errors that I have:

in case of specifying "1.15"

The error is pretty simple "Failed to parse the manifest file".

in case of specifying "1.15.0"

Dependencies could not be resolved because no versions of 'AdaptySDK-iOS' match the requirement 1.15.0..<2.0.0 and root depends on 'AdaptySDK-iOS' 1.15.0..<2.0.0.

Thank you!

Store API Keys in Keychain instead of UserDefaults

Your current implementation stores API keys in UserDefauls what is very unsafe since users can read out this keys very simple what is a huge security whole! Use keychain instead, it's very simple to implement:

// Save the user password into keychain
let keychain = Keychain(service: "com.yourcompany.yourappbundlename")
keychain["user_password"] = "correcthorsebatterystaple"

// Load the user password
let keychain = Keychain(service: "com.yourcompany.yourappbundlename")
let user_password = keychain["user_password"]

Offline support of Adapty.getPaywalls() for SKTestSession in UITests

Adapty SDK doesn't support SKTestSession in UITests.

The problem arise because Adapty.getPaywalls() doesn't return any PaywallModel when you are offline. Also Adapty.setFallbackPaywalls(paywalls) doesn't resolve this issue. I doesn't receive any PaywallModel when I'm offline after calling Adapty.getPaywalls() but an error. As a consequence I can not display any products and not do a successful UITest when I'm offline.

A possible workaround would be, if you provide an additional API call getFallbackPaywallModel() to get the fallback paywall PaywallModel. Then it would be possible to display those received products when I'm offline during UITests.

Main Thread Checker fails on Adapty.getPaywalls call from other that main thread

There's functions call-chain:
Adapty.getPaywalls -> IAPManager.getPaywalls -> IAPManager.getPaywallsAndSyncProducts.

IAPManager.getPaywallsAndSyncProducts uses UIApplication under the hood. As result Adapty.getPaywalls call from other that main thread fails Main Thread Checker.

Expected behaviour: Adapty.getPaywalls can be called from any thread.

setFallbackPaywalls returns error

Hi Adapty Team!
I'm trying to use fallback feature with offline. I loaded fallback-json from dashboard and then added it into a project.
Afterwards i try set fallback from file:

private func fetchFallback() {
        let file = R.file.fallback_paywallsJson
        if let path = Bundle.main.path(forResource: file.name, ofType: file.pathExtension),
           let paywall = try? String(contentsOfFile: path, encoding: .utf8) {
            Adapty.setFallbackPaywalls(paywall, completion: { error in
                if let error = error {
                    Log.error(error)
                }
            })
        }
    }

In completion block i get an error "An unknown error occurred".

[BackgroundTask] Background Task 9 ("SKReceiptRefreshRequest"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.

Hi, im gettin that error when I called makePurchase method

2022-09-21 19:15:46.240154+0300 WidgetCreatorApp[2573:408467] [BackgroundTask] Background Task 9 ("SKReceiptRefreshRequest"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.

after that its re init my main app, redirecting to inited view in swiftui.
how can I handle that?

Questions with new sdk version

Hi folks,

I upgraded Adapty Sdk version from 1.16 to 2.2.0 in an ios app but I'm having some problems.

  • In the new adapty version, every time the application runs in the simulator, it asks for apple id and password and I can't get past the screen without saying "cancel". This was not available in the adapty(1.16) version I used before. Is there a solution to this, the problem is related to the development environment but it is quite annoying.

  • Every time I enter the payment screen (etc. Paywall View Controller), the "Adapty.getPaywall" function is running and I wait for a certain time while bringing the paywall name. This did not exist in the previous version and except for the first load, I did not have the problem of waiting by reading from the cache every time I entered the screen. Here, after the first screen is opened, I can cache the paywall variable to a global variable myself, but this does not seem to be best practice. how can i solve this?

Thank you so much.

Missing Objective-C Interop

Hey all,

Currently trying to use Adapty on a Kotlin Multiplatform project.

As the library is purely Swift, it's code can't be accessed via iosMain on a KMP project.

One solution is to create an obj-c interop to facilitate that.

Would be awesome to have it as standard in this library

Constant Apple ID request on the simulator

Hello!

I get an Apple ID authorization request every time I run the app on the simulator. Is this how it should be? If so, it would be nice if you could add the ability to disable this for debug mode. I didn't have such a problem with the RC service.

Adapty Mode

observer

Adapty SDK Version

2.7.0

Xcode Version

14.3.1

Installation Method

SPM

Targeted Platforms

iOS

Support new SDKs in Xcode 15.3

Hey guys!

Just wanted to bring up the new SDK issue in PR #79.
Could you rebuild the Adapty SDK with the changes from the PR ASAP ๐Ÿ™.

Objective C

Hey,

Is it possible to use your SDK with objective c project?

Thanks

Adapty SDK is failing to send an ever-growing event log to Kinesis

Scenario:

  • For some reason Adapty SDK accumulated a large event log
  • Attempting to post events to Kinesis fails because event log size is too big: Member must have length less than or equal to 500
  • Event log is still growing, posted to Kinesis and rejected every minute

Screenshot:

Screenshot 2023-03-13 at 23 56 29

Environment:

Reproduced with both 1.16.8 and 1.17.1 version of iOS SDK. Used through react-native-adapty, but event log logic is untouched by JS code, so posting this issue here.

Questions:

Is this edge case fixed in 2.x version? Can this fix be backported to 1.x branch?

Crashes with latest version 1.17.2

There are multiple crashes in SessionManager with the latest 1.17.2 release:

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000019e884388
Exception Note:  EXC_CORPSE_NOTIFY
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [16801]

Triggered by Thread:  0


Thread 0 name:
Thread 0 Crashed:
0   BoardServices                 	0x000000019e884388 -[BSServiceConnectionEndpointMonitor dealloc] + 428 (BSServiceConnectionEndpointMonitor.m:58)
1   UIKitCore                     	0x0000000183ce0918 -[UIApplication .cxx_destruct] + 76 (UIApplication.m:1406)
2   libobjc.A.dylib               	0x00000001991abd28 object_cxxDestructFromClass(objc_object*, objc_class*) + 116 (objc-class.mm:455)
3   libobjc.A.dylib               	0x00000001991a8b74 objc_destructInstance + 80 (objc-class.mm:469)
4   libobjc.A.dylib               	0x00000001991b21c8 _objc_rootDealloc + 80 (objc-runtime-new.mm:8199)
5   UIKitCore                     	0x00000001830797f0 -[UIResponder dealloc] + 156 (UIResponder.m:167)
6   UIKitCore                     	0x0000000183cc8250 -[UIApplication dealloc] + 396 (UIApplication.m:1575)
7   AppName                        	0x0000000100d3e72c partial apply for closure #1 in closure #2 in SessionsManager.trackLiveEventInBackground() + 80 (SessionsManager.swift:0)
8   AppName                        	0x0000000100cff6d4 closure #3 in KinesisManager.syncEvents(profileInstallationMetaID:secretSigningKey:accessKeyId:sessionToken:completion:) + 504 (KinesisManager.swift:110)
9   AppName                        	0x0000000100cd2c14 specialized closure #1 in closure #1 in closure #1 in RequestManager.performRequest<A>(_:router:completion:) + 188
10  AppName                        	0x0000000100ce0640 partial apply for specialized closure #1 in closure #1 in closure #1 in RequestManager.performRequest<A>(_:router:completion:) + 36
11  AppName                        	0x0000000100cd8858 specialized closure #2 in RequestManager.handleResult<A>(task:result:response:completion:) + 68 (RequestManager.swift:287)
12  AppName                        	0x0000000100cca098 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
13  libdispatch.dylib             	0x00000001805d9924 _dispatch_call_block_and_release + 32 (init.c:1517)
14  libdispatch.dylib             	0x00000001805db670 _dispatch_client_callout + 20 (object.m:560)
15  libdispatch.dylib             	0x00000001805e9b70 _dispatch_main_queue_callback_4CF + 944 (inline_internal.h:2601)
16  CoreFoundation                	0x0000000180921d84 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1795)
17  CoreFoundation                	0x00000001808dbf5c __CFRunLoopRun + 2540 (CFRunLoop.c:3144)
18  CoreFoundation                	0x00000001808ef468 CFRunLoopRunSpecific + 600 (CFRunLoop.c:3268)
19  GraphicsServices              	0x000000019c49338c GSEventRunModal + 164 (GSEvent.c:2200)
20  UIKitCore                     	0x00000001832925d0 -[UIApplication _run] + 1100 (UIApplication.m:3493)
21  UIKitCore                     	0x0000000183010f74 UIApplicationMain + 364 (UIApplication.m:5047)
22  AppName                        	0x0000000100363ed4 main + 68 (ReminderRepository.swift:19)
23  dyld                          	0x00000001017c9aa4 start + 520 (dyldMain.cpp:879)

Add StoreKit 2 `Product` to `AdaptyPaywallProduct`

Currently there is just SKProduct in AdaptyPaywallProduct . We want to use StoreKit 2 Product instead. I checked that there is already logic (fetchSK2Products and fetchSK2ProductsInSameOrder methods) for fetching and caching StoreKit 2 Products, so is it possible to add it to AdaptyPaywallProduct?

OneSignal Integration is broken

This code does not save oneSignalSubscriptionId property, even though a property "one_signal_subscription_id" is sent to the server according to Debug logs.
Adapty SDK version 2.9.4

let builder = AdaptyProfileParameters.Builder()
                        .with(amplitudeDeviceId: amplitudeID)
                        .with(mixpanelUserId: mixpanelID)
                        .with(oneSignalSubscriptionId: "test_subscription_id")
                        .with(pushwooshHWID: "test_push_woosh")
                        .with(oneSignalPlayerId: "test_player_id")

try await Adapty.updateProfile(params: builder.build())
Screenshot 2024-02-12 at 1 26 57 PM

The issue leads to the integration is not working

Plan for removal of deprecated iAd framework from Adapty SDK

Hello Adapty Team,

I wanted to bring to your attention that the iAd framework has been officially deprecated by Apple. Furthermore, I recently received a communication from Apple indicating that the iAd framework will be completely removed from iOS within the next 2 years. Post-removal, any applications still utilizing iAd will experience crashes.

Given the critical nature of this update and to ensure a smooth user experience for applications leveraging the Adapty SDK, could you please share any plans or timelines regarding the removal of iAd usage within the SDK?

Thank you for your attention to this matter, and I look forward to your response.

PurchaserInfo not updated when internet connection is not available

Our application replies on Adapty purchaser info by using AdaptyDelegate.didReceiveUpdatedPurchaserInfo. Adapty requests PurchaserInfo from backed in Adapty.activate method. But didReceiveUpdatedPurchaserInfo not reported when internet connection is not available.

There's an option to get PurchaserInfo, i.e. Adapty.getPurchaserInfo(forceUpdate:). So the there's a flow:

  1. call Adapty.activate
  2. call Adapty.getPurchaserInfo(forceUpdate: false)

this entails possible two requests to simultaneous requests to backed when internet is available. What is not optimal.

So I propose two options.

  1. Call AdaptyDelegate.didReceiveUpdatedPurchaserInfo in private func configure(_ completion: ErrorCompletion? = nil) when purchaserInfo is not empty, before identify or getPurchaserInfo calls. #54
  2. Add Adapty.getPurchaserInfo(forceUpdate:) option to skip network request.

Thanks!

logShowPaywall from SwiftUI Demo not working

Hey,

We are using PaywallService from SwiftUI Demo and it's looks like that
func logPaywallDisplay() { paywall.map { Adapty.logShowPaywall($0) } }
Not working properly, since we have implemented this service class in a few projects and calling it .onAppear but no logged events displaying in the Adapty Dashboard.

Could you please check your code and confirm that it's actual and working

Critical IAP Bug

There is a critical issue where Adapty is returning no subscriptions for existing and new active subscribers. We are getting lots of emails from customers the past few hours complaining that they paid and the app is still locked. We have not changed or updated our app. We have been using Adapty for about a year. Please look into this ASAP as it's impacting us financially and this is a major concern.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.