Home > Enterprise >  Understanding iOS stack trace in crash logs
Understanding iOS stack trace in crash logs

Time:11-08

I have a strange situation where my app loads its in-app store view fine in testing including via testflight, but when downloaded from the appstore it crashes. I've found the relevant crash log below but I'm not sure exactly which parts relate to my code vs things happening under the hood.

This is the stack trace:

Thread 4 Crashed:
0   My app          0x00000001001b7908 Swift runtime failure: Index out of range   0 (<compiler-generated>:0)
1   My app          0x00000001001b7908 subscript.get   20 (<compiler-generated>:0)
2   My app          0x00000001001b7908 specialized Store.productsRequest(_:didReceive:)   1376
3   My app          0x00000001001b75e8 list.get   28 (Store.swift:0)
4   My app          0x00000001001b75e8 specialized Store.productsRequest(_:didReceive:)   576
5   My app          0x00000001001b5d8c productsRequest   12 (<compiler-generated>:0)
6   My app          0x00000001001b5d8c @objc Store.productsRequest(_:didReceive:)   76
7   StoreKit                        0x00000001ab0f8070 __27-[SKProductsRequest _start]_block_invoke_2   136 (SKProductsRequest.m:104)
8   libdispatch.dylib               0x000000018f5404b4 _dispatch_call_block_and_release   32 (init.c:1518)
9   libdispatch.dylib               0x000000018f541fdc _dispatch_client_callout   20 (object.m:560)
10  libdispatch.dylib               0x000000018f5450c8 _dispatch_queue_override_invoke   788 (inline_internal.h:2632)
11  libdispatch.dylib               0x000000018f553a6c _dispatch_root_queue_drain   396 (inline_internal.h:0)
12  libdispatch.dylib               0x000000018f554284 _dispatch_worker_thread2   164 (queue.c:7052)
13  libsystem_pthread.dylib         0x00000001d49e4dbc _pthread_wqthread   228 (pthread.c:2631)
14  libsystem_pthread.dylib         0x00000001d49e4b98 start_wqthread   8

From this I'm reading that there's something going wrong in the call to productsRequest so here is that function:

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        let myProduct = response.products
        for product in myProduct {
            list.append(product)
        }
        // Update labels
        localTitle = list[0].localizedTitle
        localDescription = list[0].localizedDescription
        
        // Format the price and display
        let formatter = NumberFormatter()
        formatter.locale = Locale.current
        formatter.numberStyle = .currency
        if let formattedPrice = formatter.string(from: list[0].price){
            localPrice = ("Upgrade: \(formattedPrice)")
            delegate?.storeUpdateReceived(store: self)
        }
    }

Here's what I'm not sure about though. Can we identify where within that function the issue is? Or is the issue getting triggered before we actually step into lines within the function? I can't repro the crash outside of the live environment so I don't think I can add breakpoints in a live installed app.

I see the index out of range error, but is that likely caused by where I'm referencing the first element in my lists (where maybe it's empty)? Or could that index be something else?

CodePudding user response:

From the available information, we can assume it is crashing on the line where you are referring the first element of list. It will surely crash if the list is empty, you can write it like this:

 func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        let myProduct = response.products
        for product in myProduct {
            list.append(product)
        }
        // Update labels
        localTitle = list.first?.localizedTitle ?? ""
        localDescription = list.first?.localizedDescription ?? ""
        
        // Format the price and display
        let formatter = NumberFormatter()
        formatter.locale = Locale.current
        formatter.numberStyle = .currency
        if let price = list.first?.price, let formattedPrice = formatter.string(from: price){
            localPrice = ("Upgrade: \(formattedPrice)")
            delegate?.storeUpdateReceived(store: self)
        }
    }
  • Related