exponea / exponea-ios-sdk

MIT License
19 stars 27 forks source link

InAppContentBlocks doesn't work on iOS #55

Closed HannaDigis closed 4 months ago

HannaDigis commented 7 months ago

When I was trying to implement InAppContentBlocks I faced up with difficulties.

Installation via CocoaPods: pod "ExponeaSDK", "~> 2.20.0" Xcode Version 15.0.1 (15A507) Min target: 13.0 Destination: iPhone Testing devices: real device iPhone 11, simulator iPhone 15 Pro, iPhone 15 Pro Max

Intro: ExponeaSDK have been successfully installed before and iOS team use it for push notifications and other features. The problem is exactly with InAppContentBlocks and only on iOS, Android works fine.

Steps for implementation: I created instances of StaticInAppContentBlockView with both init options (with and without deferredLoad) Added both BlockView to view using view.addSubview(placeholder), added constraints. For blockView with deferredLoad I used placeholder.contentReadyCompletion as It was written in docs. After that, I called reload() for both But nothing appeared, there wasn't any content in blocks. I also tried to implement it for tableView, collectionView, WKWebView, add BlocksView to another UIView, show one block at time, show both at the same time - result was the same.

Logs that was received: placeholder_1 In-app content block has been loaded: true placeholder_1 In-app content block content has size of width 410.0px height 5.0px

I also received this logs: 2023-11-29 11:29:45833 [EXP-iOS] ❗️ ERROR [TelemetryManager.swift]:51 report(eventWithType:properties:): Uploading telemetry event failed. 2023-11-29 11:29:45836 [EXP-iOS] ❗️ ERROR [VSAppCenterTelemetryUpload.swift]:119 upload(data:completionHandler:): Uploading data to Visual Studio App Center failed. Error: Optional(Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_kCFStreamErrorCodeKey=-2102, NSUnderlyingError=0x600000dea430 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <CA05901A-7FFC-471F-9490-F019527B9F2F>.<3>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalUploadTask <CA05901A-7FFC-471F-9490-F019527B9F2F>.<3>" ), NSLocalizedDescription=The request timed out., NSErrorFailingURLStringKey=https://in.appcenter.ms/logs?Api-Version=1.0.0, NSErrorFailingURLKey=https://in.appcenter.ms/logs?Api-Version=1.0.0, _kCFStreamErrorDomainKey=4}) Status code: nil Response:

I downloaded demo application from repo, built and run on my test devices - I was able to see sample table view with data but still there wasn't any contentBlockView and an error with TelemetryManager showed continuously.

I will appreciate any advice/suggestions/help in implementation such feature.

adam1929 commented 7 months ago

Hi @HannaDigis thank you for reporting of your issue. I would like to ask for part of code how you add StaticInAppContentBlockView instance into your layout, especially part with constraints setup. Android and iOS layout flows work differently and it truly depends on your layout setup. For example, if you want to achieve 'auto-height' behaviour, so StaticInAppContentBlockView is of size 0x0 on start but 410x150 after content load, you should not activate bottomAnchor constraint or anything that could potentially freeze height of StaticInAppContentBlockView. But still, there are plenty of way to add Subview to Layout, please share your layout to us and we'll glad to check it. Thank you

HannaDigis commented 7 months ago

Sure! Here is my code related to StaticInAppContentBlockView:

class HomeViewController: QuoteHelperViewController {
    var placeholder = StaticInAppContentBlockView(placeholder: "placeholder_1", deferredLoad: true)
    // Here I tried both inits
    var placeholderExample = StaticInAppContentBlockView(placeholder: "placeholder_1")
        override func viewDidLoad() {
        super.viewDidLoad()
        // Color block to see actual position
        placeholder.backgroundColor = .red.withAlphaComponent(0.3)
        view.addSubview(placeholder)

         placeholder.contentReadyCompletion = { [weak self] contentLoaded in
            guard let self else {
                print( "placeholder_1 In-app content block has been loaded but deattached from view controller")
                return
            }
            print( " placeholder_1 In-app content block has been loaded: \(contentLoaded)")
            if contentLoaded {
                let contentWidth = placeholder.frame.size.width
                let contentHeight = placeholder.frame.size.height
                print( "placeholder_1 In-app content block content has size of width \(contentWidth)px height \(contentHeight)px"
                )
            }
        }
        placeholder.translatesAutoresizingMaskIntoConstraints = false
        placeholder.topAnchor.constraint(equalTo: view.topAnchor, constant: 80).isActive = true
        placeholder.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
        placeholder.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
        placeholder.reload()  
}
    Prints that I've got in lldb:     
placeholder_1 In-app content block has been loaded: true
placeholder_1 In-app content block content has size of width 410.0px height 5.0px
adam1929 commented 7 months ago

Hi @HannaDigis thank you for detailed source code and logs. I think that your code for placing Placeholder into layout is ok. Seems fine. I would like to investigate log placeholder_1 In-app content block content has size of width 410.0px height 5.0px. I remember such a case when placeholder was put into layout but no valid message has been found for it. Reason could be:

HannaDigis commented 6 months ago

Hello @adam1929. Thank you for advice. Going through your thoughts I've checked them:

adam1929 commented 6 months ago

Hi @HannaDigis we are working on more detailed logs for In-app CB flows. It may help you with this issue, mainly in case that message is not going to show due some filtration or so. Thank you for patience

adam1929 commented 5 months ago

Hi @HannaDigis new SDK has been released 2.21.2, there were some changes done in scope of InApp content blocks. Could you reproduce your issue on latest SDK? Thank you

HannaDigis commented 5 months ago

Hello @adam1929 Thank you so much for updates, I'm working on it

HannaDigis commented 5 months ago

Hi @adam1929 I've updated SDK to 2.21.3 version. I've tried both code implementation (using reload right after init and with contentReadyCompletion) In both ways I've had same result - no content. But I've received some error messages while trying to show CB [EXP-iOS] ❗️ ERROR [StaticInAppContentBlockView.swift]:220 handleUrlClick(_:): InAppCB: Placeholder placeholder_1 has invalid state - action or message is invalid [EXP-iOS] ❗️ ERROR [InAppContentBlockCallbackType.swift]:29 onError(placeholderId:contentBlock:errorMessage:): InApp Content Block is empty!!! Nothing to track Could you help me and guide where should I search for a problem? Is it something related to Bloomreach dashboard in web or it is smth with my implementation? (still, Android works fine) Or it is smth related to exactly downloading content under the hood of your SDK (but how can I access to it)

adam1929 commented 5 months ago

Hi @HannaDigis showing of CB should not invoke handleUrlClick. Errors you see are strange but 'expected' because triggering click action prematurely is invalid - no message/content is available. Can you rise this issue with support channel? We may need see detail logs from your app to find the issue. If Android is working properly, you shouldn't have any problem with setup in Bloomreach dashboard. I would like to analyze verbose logging, where could be seen some hints:

adam1929 commented 4 months ago

Hi @HannaDigis please upgrade iOS SDK to latest version. Error that has been occurring unexpectedly has been fixed in 2.22.0.