Home > Mobile >  Swift how to put array into variable. RevenueCat offerings
Swift how to put array into variable. RevenueCat offerings

Time:08-21

I have the following code from RevenueCat and I would like to put all of my offerings in a variable

The following is not working for me

func allOffering(){
  let myOfferings = Purchases.shared.getOfferings { (offerings, error) in
        if let offerings = offerings {
          // Display current offering with offerings.current
          
          
      }
    }

  // print to log
  print(myOfferings)
}

I can print all of the offerings this way however I want to put it in a value so that I can use the data in other places in the function

func allOffering(){
  let myOfferings = Purchases.shared.getOfferings { (offerings, error) in
        if let offerings = offerings {
          // Display current offering with offerings.current
          print(offerings.current)
          
      }
    }

  // print to log
  print(myOfferings)
}

CodePudding user response:

The reason it's not working is because myOfferings is being set to the closure itself, not the actual values it loads. The offerings won't be available outside of the scope of the completion closure yet because they still need to be fetched.

The point of the completion block is that you can execute code once you know for a fact that the offerings are available (or once you've received an error, to which you can then respond appropriately).

The easiest thing to do is to perform any action you need myOfferings for inside that completion block - or pass the values as a parameter to other functions:

Purchases.shared.getOfferings { [weak self] (offerings, error) in
    if let offerings = offerings {
      self?.doSomething(with: offerings)
  }
}

func doSomething(with offers: [Offer]) {
    // do something
}

That might already address what you need. If not, there are other options.

An approach I like to take when I need access to values like this independently from the completion block is to use a LoadingState wrapper, which I can then use to see if the values are available yet. For example:

enum OfferingsLoadingState {
    case initialized
    case loaded([Offering])
    case error(Error)
}

Then I can make a variable like this:

var myOfferings: OfferingLoadingState = .initialized

And set its value to the fetched offerings once it's done:

Purchases.shared.getOfferings { [weak self] (offerings, error) in
    if let offerings = offerings {
      self?.myOfferings = .loaded(offerings)
  }
}

When using myOfferings outside of the completion block, you can then check if it's loaded and if it is get the values from it.

switch myOfferings {
    case .loaded(let offerings):
        print(offerings)
    default:
        // TODO: do something here if needed
        break
  • Related