Class: Xcode::Resource
- Inherits:
-
Object
- Object
- Xcode::Resource
- Defined in:
- lib/xcode/resource.rb
Overview
Resources are not represented as a true entity within an Xcode project. However when traversing through groups, targets, configurations, etc. you will find yourself interacting with these objects. As they represent a class that acts as a shim around their hash data.
The goal of the Resource is to aid in the navigation through the project and provide a flexible system to allow for Xcoder to adapt to changes to the Xcode project format.
A Resource requires an identifier and an instance of the Registry. Based on the supplied identifier, it peforms a look up of it’s properties or hash of data. With that hash it then proceeds to create methods that allow for easy read/write access to those property elements. This is similar to Ruby’s OpenStruct.
In the above example, you can still gain access to the internal properties through the #properties method. However, the Resource provides for you additional ruby friendly methods to access the properties.
To provide additional convenience when traversing through the various objects, the getter methods will check to see if the value being returned matches that of a unique identifier. If it does, instead of providing that identifier, it will instead look in the Registry for the object that matches and return a new Resource automatically.
In this example when accessing the first element of children instead of an identifier string being returned the child resource is returned. This functionality is in place to allow Xcoder to flexibly conform to new relationships that may exist or come to exist.
Lastly, a Resource is simply not enough to describe most of the objects within an Xcode project as each object has unique functionality that needs to be able to perform. So each resource when it is created will query the Xcode::Registry.isa_to_module hash to determine the functionality that it needs to additionally extend into the Resource.
This ‘isa` property mapped to Ruby modules allows for the easy expansion of new objects or for changes to be made to existing ones as needed.
Instance Attribute Summary collapse
-
#identifier ⇒ String
The unique identifier for this resource.
-
#properties ⇒ Hash
The raw properties hash that is known about the resource.
-
#registry ⇒ Registry
readonly
The registry of all objects within the project file which all resources have a reference to so that they can retrieve any items they may own that are simply referenced by identifiers.
Instance Method Summary collapse
-
#define_property(name, value) ⇒ Object
Definiing a property allows the creation of an alias to the actual value.
-
#initialize(identifier, registry) ⇒ Resource
constructor
A Resource is created during Project#initialize, when the project is first parsed.
-
#save! ⇒ Resource
Saves the current resource back to the registry.
-
#to_s ⇒ String
A representation with the identifier and the properties for this resource.
-
#to_xcplist ⇒ String
This will generate the resource in the format that is supported by the Xcode project file.
Constructor Details
#initialize(identifier, registry) ⇒ Resource
A Resource is created during Project#initialize, when the project is first parsed. Afterwards each Resource is usually generated through the special getter method defined through #define_property.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/xcode/resource.rb', line 180 def initialize identifier, registry @registry = registry @properties = {} @identifier = identifier # Create property methods for all of the key-value pairs found in the # registry for specified identifier. Array(registry.properties(@identifier)).each do |key,value| send :define_property, key, value end # # Based on the `isa` property find if there are constants within # the Xcode module that matches and if it does, then we want to # automatically include those modules into the Resource object. # constants = Registry.isa_to_module(isa) constants.each do |constant| self.extend(constant) if constant end end |
Instance Attribute Details
#identifier ⇒ String
Returns the unique identifier for this resource.
85 86 87 |
# File 'lib/xcode/resource.rb', line 85 def identifier @identifier end |
#properties ⇒ Hash
The raw properties hash that is known about the resource. This is the best way to manipulate the raw values of the resource.
91 92 93 |
# File 'lib/xcode/resource.rb', line 91 def properties @properties end |
#registry ⇒ Registry (readonly)
The registry of all objects within the project file which all resources have a reference to so that they can retrieve any items they may own that are simply referenced by identifiers. This registry is used to convert identifier keys to resource objects. It is also passed to any resources that are created.
100 101 102 |
# File 'lib/xcode/resource.rb', line 100 def registry @registry end |
Instance Method Details
#define_property(name, value) ⇒ Object
This is used internally by the resource when it is created to create the getter/setter methods.
Definiing a property allows the creation of an alias to the actual value. This level of indirection allows for the replacement of values which are identifiers with a resource representation of it.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/xcode/resource.rb', line 113 def define_property name, value # Save the properties within the resource within a custom hash. This # provides access to them without the indirection that we are about to # set up. @properties[name] = value # Generate a getter method for this property based on the given name. self.class.send :define_method, name.underscore do # Retrieve the value that is current stored for this name. raw_value = @properties[name] # If the value is an array then we want to examine each element within # the array to see if any of them are identifiers that we should replace # finally returning all of the items as their resource representations # or as their raw values. # # If the value is not an array then we want to examine that item and # return the resource representation or the raw value. if raw_value.is_a?(Array) Array(raw_value).map do |sub_value| if Registry.is_identifier? sub_value Resource.new sub_value, @registry else sub_value end end else if Registry.is_identifier? raw_value Resource.new raw_value, @registry else raw_value end end end # Generate a setter method for this property based on the given name. self.class.send :define_method, "#{name.underscore}=" do |new_value| @properties[name] = new_value end end |
#save! ⇒ Resource
Saves the current resource back to the registry. This is necessary as any changes made are not automatically saved back into the registry.
217 218 219 220 |
# File 'lib/xcode/resource.rb', line 217 def save! @registry.set_object(self) self end |
#to_s ⇒ String
Returns a representation with the identifier and the properties for this resource.
226 227 228 |
# File 'lib/xcode/resource.rb', line 226 def to_s "#{isa} #{@identifier} #{@properties}" end |
#to_xcplist ⇒ String
This will generate the resource in the format that is supported by the Xcode project file. Which requires each key value pair to be represented.
237 238 239 240 241 |
# File 'lib/xcode/resource.rb', line 237 def to_xcplist %{ #{@identifier} = { #{ @properties.map {|k,v| "#{k} = \"#{v.to_xcplist}\"" }.join("; ") } } } end |