Automating IAP creation in iTunes Connect

Adding in app purchases via the iTunes Connect dashboard can be a pain. I happened to have to add 45 IAPs to a game recently, and I used this method to do it in 10 minutes.

You’ll need:

  1. Ruby installed
  2. A csv with all your IAPs – like this iaps.csv
  3. The ruby script bellow
#!/usr/bin/env ruby
require 'io/console'
require "spaceship"
require 'csv'
 
puts "Enter password"
pass = STDIN.noecho(&:gets)
Spaceship::Tunes.login("<your-username>", pass)
app = Spaceship::Tunes::Application.find("<your-app-id>")
 
CSV.foreach("/Users/<user>/iaps.csv", quote_char: '"', col_sep: ',', row_sep: :auto, headers: true) do |row|
	productType = row['Type (consumable -1, non-consumable -2)'] == "1" ? Spaceship::Tunes::IAPType::CONSUMABLE : Spaceship::Tunes::IAPType::NON_CONSUMABLE
	productName = row['Reference Name']
	productDescription = row['IAP description-EN']
	productIdentifier = row['Product ID']
	productTier = row['IAP Price-TIER'].to_i
	puts "Processing product '%s', it's a '%s' %s of tier %d" % [productIdentifier, productName, productType, productTier]
	app.in_app_purchases.create!(
		type: productType, 
		versions: {
		  "en-US" => {
		    name: productName,
		    description: productDescription
		  }
		},
		reference_name: productName,
		product_id: productIdentifier,
		cleared_for_sale: true,
		review_notes: "",
		review_screenshot: "/Users/<username>/Downloads/default.jpg", 
		pricing_intervals: 
		  [
		    {
		      country: "WW",
		      begin_date: nil,
		      end_date: nil,
		      tier: productTier
		    }
		  ] 
		)
end

If you still can’t get it to work, or want to know more, check out:

  1. Creating In-app purchase records on iTunes Connect programmatically
  2. Automatically create in-apps in iTunesConnect with iMacros
  3. How to parse CSV data with Ruby

Item Affix System in Unity C# with the Decorator Pattern

Ever wanted to do:

var awesomeNewHat = new OfProgramming( new Sagacious( new WizardHat() ) );
awesomeNewHat.Use();

Well, I used to, that’s why I implemented an affix system with the decorator pattern. Code available here – https://github.com/abeldantas/item-affix-decorators

> Puts on Sagacious Wizard Hat of Programming

An affix system is the sort of thing every loot based RPG needs to have satisfying item names and effects.

Here, have some hats:Unity WebGL Player | item-affix-decorators


The decorators are the affixes, an item is a component, and the Wizard Hat in this case is a concrete item.

The decorator pattern can model a lot of fun stuff in games.
Making a skill system should be fun too, where the decorating order factors into what effects you get.

Don’t put off loading scenes until later if you can load them asynchronously now

I used to struggle to find clean ways to load unity scenes.

Then I stopped struggling and started using the snippet bellow while I wait for a cleaner approach.

using System;
using UnityEngine;
using System.Collections;
using UnityEngine.Assertions;
using UnityEngine.SceneManagement;
 
public class AsyncSceneLoader
{
    readonly string sceneName;
    public AsyncOperation async;
 
    public AsyncSceneLoader( string sceneName )
    {
        this.sceneName = sceneName;
    }
 
    public void Load()
    {
        Assert.IsFalse( string.IsNullOrEmpty( sceneName ) );
        AsyncSceneLoaderWizard.Instance.StartCoroutine( Load( sceneName ) );
    }
 
    IEnumerator Load( string sceneName )
    {
        if ( string.IsNullOrEmpty( sceneName ) )
        {
            throw new Exception( "Can't load empty string as scene name" );
        }
 
        async = SceneManager.LoadSceneAsync( sceneName );
        async.allowSceneActivation = false;
        yield return async;
    }
 
    public void Activate()
    {
        async.allowSceneActivation = true;
    }
}
 
public class AsyncSceneLoaderWizard : GameObjectSingleton<AsyncSceneLoaderWizard>
{
    public static AsyncSceneLoader SettingsSceneLoader = new AsyncSceneLoader( "Settings Scene" );
 
    public static AsyncSceneLoader EndgameCreditsSceneLoader = new AsyncSceneLoader( "Endgame Credits" );
 
    public void Start()
    {
        SettingsSceneLoader.Load();
        EndgameCreditsSceneLoader.Load();
    }
}

You shall seek and always find with this generic seeker type pattern

Imagine you have a bunch of popup templates that you want to use across a codebase.

You have a bunch of prefabs for those popups.

You can use the logic I’m about to describe to do stuff like:

Popup.Find<YourPizzaIsReadyPopup>().Show()

Disclaimer: Don’t overuse this or you’ll have spaghetti code.

Ok, let’s go, I called this the seeker pattern, because it helps you find stuff.
Have a better name? Cool, keep it to yourself.

public static class SeekableExtensions
{
    public static bool IsOfSeekableType<T>( this Seekable seekable ) where T : Seekable
    {
        return seekable.GetType() == typeof(T);
    }
}
 
public interface Seekable
{
    void Seek();
}
 
public class UnassumingBystander : Seekable
{
    public void Seek()
    {
        Debug.Log( "Oh, you found me..." );
    }
}
 
internal class SeekableNotFoundException : Exception
{
}
 
// A wizard is a singleton
public class Wizard
{
    List<Seekable> seekables;
 
    T GetSeekable<T>() where T : Seekable
    {
        foreach ( var arcanizer in seekables )
        {
            if ( arcanizer.IsOfSeekableType<T>() )
            {
                return (T)arcanizer;
            }
        }
        throw new SeekableNotFoundException();
    }
 
 
    void DoStuff()
    {
        GetSeekable<UnassumingBystander>().Seek();
    }
}