class Spaceship::Base

When you want to instantiate a model pass in the parsed response: ‘Widget.new(widget_json)`
end
})
’wizBaz’ => :wiz_baz
’fooBar’ => :foo_bar,
‘name’ => :name,
attr_mapping({
attr_accessor :id, :name, :foo_bar, :wiz_baz
class Widget < Spaceship::Base
Example of creating a new ADP model:
are using to talk to ADP.
A class-level attribute ‘client` is used to maintain the spaceship which we
It’s mainly responsible for mapping responses to objects.
Spaceship::Base is the superclass for models in Apple Developer Portal.
#

def self.attr_accessor(*vars)

This will store a list of defined attr_accessors to easily access them when inspecting the values
From https://stackoverflow.com/questions/2487333/fastest-one-liner-way-to-list-attr-accessors-in-ruby
def self.attr_accessor(*vars)
  @attributes ||= []
  @attributes.concat vars
  super(*vars)
end

def self.attributes

def self.attributes
  @attributes ||= []
  par = []
  par = (self.superclass.attributes || []) unless self == Base
  @attributes + par
end

def attr_mapping(attr_map = nil)

end
})
'wizBaz' => :wiz_baz
'fooBar' => :foo_bar,
'name' => :name,
attr_mapping({
attr_accessor :id, :name, :foo_bar, :wiz_baz
class Widget < Spaceship::Base

Example of using `attr_mapping`

Keys are to match keys in the response and the values are to match attributes on the model.
Defines the attribute mapping between the response from Apple and our model objects.
#
def attr_mapping(attr_map = nil)
  if attr_map
    @attr_mapping = attr_map
    @attr_mapping.values.each do |method_name|
      getter = method_name.to_sym
      setter = "#{method_name}=".to_sym
      remove_method(getter) if public_instance_methods.include?(getter)
      remove_method(setter) if public_instance_methods.include?(setter)
    end
    include(mapping_module(@attr_mapping))
  else
    begin
      @attr_mapping ||= ancestors[1].attr_mapping
    rescue NameError, NoMethodError
    end
  end
  return @attr_mapping
end

def attributes

def attributes
  self.class.attributes
end

def client

Returns:
  • (Spaceship::Client) - Defaults to the singleton
def client
  raise "`client` must be implemented in subclasses"
end

def initialize(attrs = {})

Do not override `initialize` in your own models.

attributes that are defined by `attr_mapping`
The initialize method accepts a parsed response from Apple and sets all
#
def initialize(attrs = {})
  attrs.each do |key, val|
    self.send("#{key}=", val) if respond_to?("#{key}=")
  end
  self.raw_data = DataHash.new(attrs)
  @client = self.class.client
  self.setup
end

def inspect

def inspect
  inspectables = self.attributes
  value = inspectables.map do |k|
    v = self.send(k).inspect
    v.gsub!("\n", "\n\t") # to align nested elements
    "\t#{k}=#{v}"
  end.join(", \n")
  "<#{self.class.name} \n#{value}>"
end

def mapping_module(attr_mapping)

Returns:
  • (Module) - with the mapped getters and setters defined. Can be `include`, `extend`, or `prepend` into a class or object
def mapping_module(attr_mapping)
  Module.new do
    attr_mapping.each do |source, dest|
      getter = dest.to_sym
      setter = "#{dest}=".to_sym
      define_method(getter) do
        raw_data.get(*source.split('.'))
      end
      define_method(setter) do |value|
        self.raw_data ||= DataHash.new({})
        raw_data.set(source.split('.'), value)
      end
    end
  end
end

def method_missing(method_sym, *args, &block)

#=> NoMethodError: undefined method `some_other_method' for ProvisioningProfile
ProvisioningProfile.some_other_method

#=> ProvisioningProfile::AdHoc
ProvisioningProfile.ad_hoc

#=> Certificate::ProductionPush
Certificate.production_push

Example:

If the method does not match, NoMethodError is raised.
return the class with the current client passed into it.
If `method_sym` is an underscored name of a class,

Call a method to return a subclass constant.
#
def method_missing(method_sym, *args, &block)
  module_name = method_sym.to_s
  module_name.sub!(/^[a-z\d]/) { $&.upcase }
  module_name.gsub!(%r{(?:_|(/))([a-z\d])}) { $2.upcase }
  if const_defined?(module_name)
    klass = const_get(module_name)
    klass.set_client(@client)
  else
    super
  end
end

def set_client(client)

Returns:
  • (Spaceship::Base) -
def set_client(client)
  self.client = client
  self
end

def setup

using the `raw_data`
This method can be used by subclasses to do additional initialisation
def setup
end

def to_s

def to_s
  self.inspect
end