xcoder 0.1.4 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,8 +1,23 @@
1
- *.gem
1
+
2
+ # Dependency management
3
+
2
4
  .bundle
3
5
  Gemfile.lock
6
+
7
+ # Documentation
8
+
9
+ .yardoc
10
+ doc/
11
+
12
+ # Gem creation and packaging
13
+
4
14
  pkg/*
15
+ *.gem
16
+
17
+ # Tests and Test Related Files
18
+
5
19
  spec/TestProject/TestProject.xcodeproj/xcuserdata
6
20
  spec/TestProject/TestProject.xcodeproj/project.xcworkspace/
7
21
  spec/TestProject/build
8
- spec/test-reports
22
+ spec/test-reports
23
+
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # XCoder
2
2
 
3
- A ruby wrapper around various xcode tools and project, schemes and workspace configuration files
3
+ Taking the pain out of scripting and automating xcode builds.
4
+
5
+ Xcoder is a ruby wrapper around various Xcode tools as well as providing project and workspace parsing and partial write support. Xcoder also supports manipulation of keychains, packaging and uploading artifacts to [Testflight](http://testflightapp.com) and provisioning profile management.
4
6
 
5
7
  Full documentation can be found here: http://rayh.github.com/xcoder/
6
8
 
@@ -111,9 +113,9 @@ Or enumerate installed profiles:
111
113
  p.uninstall # Removes the profile from ~/Library/
112
114
  end
113
115
 
114
- ### Testflight
116
+ ### [Testflight](http://testflightapp.com)
115
117
 
116
- The common output of this build/package process is to upload to testflight. This is pretty simple with xcoder:
118
+ The common output of this build/package process is to upload to Testflight. This is pretty simple with Xcoder:
117
119
 
118
120
  builder.testflight(API_TOKEN, TEAM_TOKEN) do |tf|
119
121
  tf.notes = "some release notes"
@@ -133,6 +135,64 @@ You can invoke your test target/bundle from the builder
133
135
 
134
136
  This will invoke the test target, capture the output and write the junit reports to the test-reports directory. Currently only junit is supported.
135
137
 
138
+ ## Manipulating a Project
139
+
140
+ Xcoder can also create targets, configurations, and add files. Xcoder could be used to programmatically manipulate or install external sources into a project.
141
+
142
+ It is important to note that Xcode gets cranky when the Xcode project file is changed by external sources. This usually causes the project and schemes to reset or maybe even cause Xcode to crash. It is often best to close the project before manipulating it with Xcoder.
143
+
144
+ ### Add the source and header file to the project
145
+
146
+ # Copy the physical source files into the project path `Vendor/Reachability`
147
+ FileUtils.cp_r "examples/Reachability/Vendor", "spec/TestProject"
148
+
149
+ source_files = [ { 'name' => 'Reachability.m', 'path' => 'Vendor/Reachability/Reachability.m' },
150
+ { 'name' => 'Reachability.h', 'path' => 'Vendor/Reachability/Reachability.h' } ]
151
+
152
+
153
+ # Create and traverse to the group Reachability within the Vendor folder
154
+ project.group('Vendor/Reachability') do
155
+ # Create files for each source file defined above
156
+ source_files.each |source| create_file source }
157
+ end
158
+
159
+
160
+ Within the project file the groups in the path are created or found and then file references are added for the two specified source files. Xcoder only updates the logical project file, it does not copy physical files, that is done by the FileUtils.
161
+
162
+
163
+ ### Adding source file to the sources build phase
164
+
165
+ source_file = project.file('Vendor/Reachability/Reachability.m')
166
+
167
+ # Select the main target of the project and add the source file to the build phase.
168
+
169
+ project.target('TestProject').sources_build_phase do
170
+ add_build_file source_file
171
+ end
172
+
173
+ Adding source files does not automatically include it in any of the built targets. That is done after you add the source file to the `sources_build_phase`. First we find the source file reference, select our target and then add it as a build file.
174
+
175
+ ### Adding a System Framework
176
+
177
+ cfnetwork_framework = project.frameworks_group.create_system_framework 'CFNetwork'
178
+
179
+ project.target('TestProject').framework_build_phase do
180
+ add_build_file cfnetwork_framework
181
+ end
182
+
183
+ The **CFNetwork.framework** is added to the `Frameworks` group of the project and then added to the frameworks build phase.
184
+
185
+ ### Saving your changes!
186
+
187
+
188
+ project.save!
189
+
190
+ The saved file output is ugly compared to what you may normally see when you view a Xcode project file. Luckily, Xcode will fix the format of the file if you make any small changes to the project that require it to save.
191
+
192
+ ### More Examples
193
+
194
+ Within the `specs/integration` folder there are more examples.
195
+
136
196
  ## Tests
137
197
 
138
198
  There are some basic RSpec tests in the project which I suspect /wont/ work on machines without my identity installed.
data/lib/xcode/builder.rb CHANGED
@@ -47,14 +47,18 @@ module Xcode
47
47
  cmd << "TEST_HOST=''"
48
48
 
49
49
  parser = Xcode::Test::OCUnitReportParser.new
50
- Xcode::Shell.execute(cmd, false) do |line|
51
- puts line
52
- parser << line
53
- end
54
-
55
50
  yield(parser) if block_given?
56
51
 
57
- exit parser.exit_code if parser.exit_code!=0
52
+ begin
53
+ Xcode::Shell.execute(cmd, false) do |line|
54
+ parser << line
55
+ end
56
+ rescue => e
57
+ parser.flush
58
+ # Let the failure bubble up unless parser has got an error from the output
59
+ raise e unless parser.failed?
60
+ end
61
+ exit 1 if parser.failed?
58
62
 
59
63
  self
60
64
  end
@@ -73,6 +77,7 @@ module Xcode
73
77
  cmd = []
74
78
  cmd << "xcodebuild"
75
79
  cmd << "-project \"#{@target.project.path}\""
80
+ cmd << "-sdk #{@sdk}" unless @sdk.nil?
76
81
 
77
82
  cmd << "-scheme #{@scheme.name}" unless @scheme.nil?
78
83
  cmd << "-target \"#{@target.name}\"" if @scheme.nil?
@@ -101,6 +106,14 @@ module Xcode
101
106
  cmd << "--entitlements \"#{entitlements_path}\""
102
107
  cmd << "\"#{ipa_path}\""
103
108
  Xcode::Shell.execute(cmd)
109
+
110
+ # CodeSign build/AdHoc-iphoneos/Dial.app
111
+ # cd "/Users/ray/Projects/Clients/CBAA/Community Radio"
112
+ # setenv CODESIGN_ALLOCATE /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
113
+ # setenv PATH "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/Users/ray/.rvm/gems/ruby-1.9.2-p290@cbaa/bin:/Users/ray/.rvm/gems/ruby-1.9.2-p290@global/bin:/Users/ray/.rvm/rubies/ruby-1.9.2-p290/bin:/Users/ray/.rvm/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/local/git/bin"
114
+ # /usr/bin/codesign --force --sign "iPhone Distribution: Community Broadcasting Association of Australia" "--resource-rules=/Users/ray/Projects/Clients/CBAA/Community Radio/build/AdHoc-iphoneos/Dial.app/ResourceRules.plist" --keychain "\"/Users/ray/Projects/Clients/CBAA/Community\\" "Radio/Provisioning/CBAA.keychain\"" --entitlements "/Users/ray/Projects/Clients/CBAA/Community Radio/build/CommunityRadio.build/AdHoc-iphoneos/CommunityRadio.build/Dial.xcent" "/Users/ray/Projects/Clients/CBAA/Community Radio/build/AdHoc-iphoneos/Dial.app"
115
+ # iPhone Distribution: Community Broadcasting Association of Australia: no identity found
116
+ # Command /usr/bin/codesign failed with exit code 1
104
117
  self
105
118
  end
106
119
 
@@ -110,7 +123,7 @@ module Xcode
110
123
  #package IPA
111
124
  cmd = []
112
125
  cmd << "xcrun"
113
- cmd << "-sdk #{@target.project.sdk.nil? ? "iphoneos" : @target.project.sdk}"
126
+ cmd << "-sdk #{@sdk}" unless @sdk.nil?
114
127
  cmd << "PackageApplication"
115
128
  cmd << "-v \"#{app_path}\""
116
129
  cmd << "-o \"#{ipa_path}\""
@@ -183,7 +196,7 @@ module Xcode
183
196
  cmd << "-target \"#{@target.name}\"" if @scheme.nil?
184
197
  cmd << "-configuration \"#{@config.name}\"" if @scheme.nil?
185
198
 
186
- cmd << "OTHER_CODE_SIGN_FLAGS=\"--keychain #{@keychain.path}\"" unless @keychain.nil?
199
+ cmd << "OTHER_CODE_SIGN_FLAGS='--keychain #{@keychain.path}'" unless @keychain.nil?
187
200
  cmd << "CODE_SIGN_IDENTITY=\"#{@identity}\"" unless @identity.nil?
188
201
  cmd << "OBJROOT=\"#{@build_path}\""
189
202
  cmd << "SYMROOT=\"#{@build_path}\""
@@ -1,4 +1,9 @@
1
1
  require 'xcode/builder'
2
+ require 'xcode/configurations/space_delimited_string_property'
3
+ require 'xcode/configurations/targeted_device_family_property'
4
+ require 'xcode/configurations/string_property'
5
+ require 'xcode/configurations/boolean_property'
6
+ require 'xcode/configurations/array_property'
2
7
 
3
8
  module Xcode
4
9
 
@@ -8,7 +13,7 @@ module Xcode
8
13
  # defined.
9
14
  #
10
15
  # @see https://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/Xcode4UserGuide/Building/Building.html
11
- #
16
+ #
12
17
  # Each configuration is defined and then a reference of that configuration is
13
18
  # maintained in the Target through the XCConfigurationList.
14
19
  #
@@ -29,6 +34,16 @@ module Xcode
29
34
  #
30
35
  module Configuration
31
36
 
37
+ #
38
+ # A large number of these default build settings properties for a configuration
39
+ # are as defined for Xcode 4.2.
40
+ #
41
+ # @todo remove the name requirement and replace all these configuration settings
42
+ # with the smaller subset. As a lot of these are usually maintained by the project
43
+ # @param [String] name is used to create the correct prefix header file and
44
+ # info.plist file.
45
+ # @return [Hash] properties for a default build configuration
46
+ #
32
47
  def self.default_properties(name)
33
48
  { 'isa' => 'XCBuildConfiguration',
34
49
  'buildSettings' => {
@@ -54,18 +69,138 @@ module Xcode
54
69
  end
55
70
 
56
71
  #
57
- # The configuration is defined within a target.
58
- # @see PBXNativeTarget
72
+ # This method will define getters/setters mapped to the build configuration.
59
73
  #
60
- attr_accessor :target
74
+ # This allows for dynamic values to be saved and loaded by allowing a parsing
75
+ # process to take place on the loaded value and when saving back to the value.
76
+ #
77
+ # @param [Symbol] property_name the name of the property that is being defined
78
+ # @param [String setting_name the configuration value string
79
+ # @param [Types] type is the class that is used to load and save the value
80
+ # correctly.
81
+ #
82
+ def self.property(property_name,setting_name,type)
83
+
84
+ # Define a getter method
85
+
86
+ define_method property_name do
87
+ substitute type.open(build_settings[setting_name])
88
+ end
89
+
90
+ # Define a setter method
91
+
92
+ define_method "#{property_name}=" do |value|
93
+ build_settings[setting_name] = unsubstitute(type.save(value))
94
+ end
95
+
96
+ end
61
97
 
62
98
  #
63
- # @return the location for the InfoPlist file for the configuration.
64
- # @see InfoPlist
99
+ # As configurations are defined within a target, this will return the target
100
+ # that owns this configuration through a build_configuration list.
65
101
  #
66
- def info_plist_location
67
- build_settings['INFOPLIST_FILE']
68
- end
102
+ # However, a build configuration list can also be defined at the project level
103
+ # which means target may likely be nil when viewing the configuration of
104
+ # the project.
105
+ #
106
+ # @see Target
107
+ # @see ConfigurationList
108
+ #
109
+ attr_accessor :target
110
+
111
+ # @attribute
112
+ # Build Setting - "PRODUCT_NAME"
113
+ property :product_name, "PRODUCT_NAME", StringProperty
114
+
115
+ # @attribute
116
+ # Build Setting - "SUPPORTED_PLATFORMS"
117
+ property :supported_platforms, "SUPPORTED_PLATFORMS", SpaceDelimitedString
118
+
119
+ # @attribute
120
+ # Build Setting - "GCC_PRECOMPILE_PREFIX_HEADER"
121
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW11
122
+ property :precompile_prefix_headers, "GCC_PRECOMPILE_PREFIX_HEADER", BooleanProperty
123
+
124
+ # @attribute
125
+ # Build Setting - "GCC_PREFIX_HEADER"
126
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW12
127
+ property :prefix_header, "GCC_PREFIX_HEADER", StringProperty
128
+
129
+ # @attribute
130
+ # Build Setting - "INFOPLIST_FILE"
131
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW68
132
+ property :info_plist_location, "INFOPLIST_FILE", StringProperty
133
+
134
+ # @attribute
135
+ # Build Setting - "WRAPPER_EXTENSION"
136
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW3
137
+ property :wrapper_extension, "WRAPPER_EXTENSION", StringProperty
138
+
139
+ # @attribute
140
+ # Build Setting - "TARGETED_DEVICE_FAMILY"
141
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW165
142
+ property :targeted_device_family, "TARGETED_DEVICE_FAMILY", TargetedDeviceFamily
143
+
144
+ # @attribute
145
+ # Build Setting - "SDKROOT"
146
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW89
147
+ property :sdkroot, "SDKROOT", StringProperty
148
+
149
+ # @attribute
150
+ # Build Setting - "OTHER_CFLAGS"
151
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW17
152
+ property :other_c_flags, "OTHER_CFLAGS", ArrayProperty
153
+
154
+ # @attribute
155
+ # Build Setting - "GCC_C_LANGUAGE_STANDARD"
156
+ # Usually set to gnu99
157
+ property :c_language_standard, "GCC_C_LANGUAGE_STANDARD", StringProperty
158
+
159
+ # @attribute
160
+ # Build Setting - "ALWAYS_SEARCH_USER_PATHS"
161
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW110
162
+ property :always_search_user_paths, "ALWAYS_SEARCH_USER_PATHS", BooleanProperty
163
+
164
+ # @attribute
165
+ # Build Setting - "GCC_VERSION"
166
+ # @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW15
167
+ property :gcc_version, "GCC_VERSION", StringProperty
168
+
169
+ # @attribute
170
+ # Build Setting - "ARCHS"
171
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW62
172
+ property :architectures, "ARCHS", SpaceDelimitedString
173
+
174
+ # @attribute
175
+ # Build Setting - "GCC_WARN_ABOUT_MISSING_PROTOTYPES"
176
+ # Defaults to YES
177
+ property :warn_about_missing_prototypes, "GCC_WARN_ABOUT_MISSING_PROTOTYPES", BooleanProperty
178
+
179
+ # @attribute
180
+ # Build Setting - "GCC_WARN_ABOUT_MISSING_PROTOTYPES"
181
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW123
182
+ property :warn_about_return_type, "GCC_WARN_ABOUT_RETURN_TYPE", BooleanProperty
183
+
184
+ # @attribute
185
+ # Build Setting - "CODE_SIGN_IDENTITY[sdk=>iphoneos*]"
186
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_10
187
+ property :code_sign_identity, "CODE_SIGN_IDENTITY[sdk=>iphoneos*]", StringProperty
188
+
189
+ # @attribute
190
+ # Build Setting - "VALIDATE_PRODUCT"
191
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW167
192
+ property :validate_product, "VALIDATE_PRODUCT", BooleanProperty
193
+
194
+ # @attribute
195
+ # Build Setting - "IPHONEOS_DEPLOYMENT_TARGET"
196
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW156
197
+ # @todo this should be a numeric scale from 2.0 through 5.0; at the levels specified in the documentation
198
+ property :iphoneos_deployment_target, "IPHONEOS_DEPLOYMENT_TARGET", StringProperty
199
+
200
+ # @attribute
201
+ # Build Setting - "COPY_PHASE_STRIP"
202
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW144
203
+ property :copy_phase_strip, "COPY_PHASE_STRIP", BooleanProperty
69
204
 
70
205
  #
71
206
  # Opens the info plist associated with the configuration and allows you to
@@ -83,19 +218,16 @@ module Xcode
83
218
  # @see InfoPlist
84
219
  #
85
220
  def info_plist
86
- # puts @json.inspect
87
221
  info = Xcode::InfoPlist.new(self, info_plist_location)
88
222
  yield info if block_given?
89
223
  info.save
90
224
  info
91
225
  end
92
226
 
93
- #
94
- # @return the name of the product that this configuration will generate.
95
- #
96
- def product_name
97
- substitute(build_settings['PRODUCT_NAME'])
98
- end
227
+ # @attribute
228
+ # Build Setting - "USER_HEADER_SEARCH_PATHS"
229
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW21
230
+ property :user_header_search_paths, "USER_HEADER_SEARCH_PATHS", SpaceDelimitedString
99
231
 
100
232
  #
101
233
  # Retrieve the configuration value for the given name
@@ -117,7 +249,6 @@ module Xcode
117
249
  build_settings[name] = value
118
250
  end
119
251
 
120
-
121
252
  #
122
253
  # Create a builder for this given project->target->configuration.
123
254
  #
@@ -125,11 +256,9 @@ module Xcode
125
256
  # @see Builder
126
257
  #
127
258
  def builder
128
- #puts "Making a Builder with #{self} #{self.methods}"
129
259
  Xcode::Builder.new(self)
130
260
  end
131
261
 
132
-
133
262
  private
134
263
 
135
264
  #
@@ -141,6 +270,9 @@ module Xcode
141
270
  # the target variable to replace.
142
271
  #
143
272
  # @return [String] a string without the variable reference.
273
+ #
274
+ # @todo move this to a decorator that wraps the other objects that load/save
275
+ # properties
144
276
  #
145
277
  def substitute(value)
146
278
  if value=~/\$\(.*\)/
@@ -156,6 +288,21 @@ module Xcode
156
288
  value
157
289
  end
158
290
  end
291
+
292
+ #
293
+ # @todo currently this performs no operation, but perhaps it should
294
+ # in the future to support the ability to persist intelligently back with
295
+ # paths
296
+ #
297
+ # @param [Object] value the object that is scanned to figure out if it
298
+ # should have content values replaced with environment variables
299
+ #
300
+ # @todo move this to a decorator that wraps the other objects that load/save
301
+ # properties
302
+ #
303
+ def unsubstitute(value)
304
+ value
305
+ end
159
306
 
160
307
  end
161
308
  end
@@ -0,0 +1,33 @@
1
+
2
+ module Xcode
3
+ module Configuration
4
+
5
+ #
6
+ # Within the a build settings for a configuration there are a number of
7
+ # settings that are stored as Arrays. This helper module is for the most part
8
+ # a pass-through method to provide parity with the other methods.
9
+ #
10
+ module ArrayProperty
11
+ extend self
12
+
13
+ #
14
+ # As arrays are stored as arrays this is not particularly different.
15
+ #
16
+ # @param [Array] value to be parsed into the correct format
17
+ #
18
+ def open(value)
19
+ value.to_a
20
+ end
21
+
22
+ #
23
+ # @param [Nil,Array,String] value that is being saved back which can
24
+ # be in a multitude of formats as long as it responds_to? #to_a
25
+ #
26
+ def save(value)
27
+ value.to_s
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+
2
+ module Xcode
3
+ module Configuration
4
+
5
+ #
6
+ # Within the a build settings for a configuration there are a number of
7
+ # settings that are stored as Objective-C boolean values. This helper module
8
+ # provides the opening and saving of these values.
9
+ #
10
+ # When opened the value returns is going to be an Array.
11
+ #
12
+ # @example setting and getting a property
13
+ #
14
+ # debug_config project.target('SomeTarget').config('Debug')
15
+ # debug_config.always_search_user_paths # => false
16
+ # debug_config.always_search_user_paths = true
17
+ # debug_config.always_search_user_paths # true
18
+ #
19
+ module BooleanProperty
20
+ extend self
21
+
22
+ #
23
+ # @param [Nil,TrueClass,FalseClass,String] value to convert to boolean
24
+ # @return [TrueClass,FalseClass] the boolean value based on the specified
25
+ # value.
26
+ #
27
+ def open(value)
28
+ value.to_s =~ /^YES$/
29
+ end
30
+
31
+ #
32
+ # @param [String,FalseClass,TrueClass] value to convert to the Obj-C boolean
33
+ # @return [String] YES or NO
34
+ #
35
+ def save(value)
36
+ value.to_s =~ /^(?:NO|false)$/ ? "NO" : "YES"
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,47 @@
1
+
2
+ module Xcode
3
+ module Configuration
4
+
5
+ #
6
+ # Within the a build settings for a configuration there are a number of
7
+ # settings that are stored a space-delimited strings. This helper module
8
+ # provides the opening and saving of these values.
9
+ #
10
+ # When opened the value returns is going to be an Array.
11
+ #
12
+ # @example common build settings that are space delimited
13
+ #
14
+ # Supported Platforms : SUPPORTED_PLATFORMS
15
+ # User Header Search Paths : USER_HEADER_SEARCH_PATHS
16
+ # Other Test Flags : OTHER_TEST_FLAGS
17
+ #
18
+ # @example setting and getting supported platforms
19
+ #
20
+ # debug_config project.target('SomeTarget').config('Debug')
21
+ # debug_config.supported_platforms # => []
22
+ # debug_config.supported_platforms = "PLATFORM A"
23
+ # debug_config.supported_platforms # => [ "PLATFORM A" ]
24
+ #
25
+ module SpaceDelimitedString
26
+ extend self
27
+
28
+ #
29
+ # @param [Nil,String] value stored within the build settings
30
+ # @return [Array<String>] a list of the strings that are within this string
31
+ #
32
+ def open(value)
33
+ value.to_s.split(" ")
34
+ end
35
+
36
+ #
37
+ # @param [Array,String] value to be converted into the correct format
38
+ # @return [String] the space-delimited string
39
+ #
40
+ def save(value)
41
+ Array(value).join(" ")
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+
2
+ module Xcode
3
+ module Configuration
4
+
5
+ #
6
+ # Within the a build settings for a configuration there are a number of
7
+ # settings that are stored simply as strings. This helper module
8
+ # is for the most part a pass-through method to provide parity with the
9
+ # other methods.
10
+ #
11
+ module StringProperty
12
+ extend self
13
+
14
+ def open(value)
15
+ value.to_s
16
+ end
17
+
18
+ def save(value)
19
+ value.to_s
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+
2
+ module Xcode
3
+ module Configuration
4
+
5
+ #
6
+ # Within the a build settings there is a setting for the Targeted Device
7
+ # Family which assigns particular numeric values to the platform types.
8
+ #
9
+ # Instead of manipulating the numeric values, this will perform a conversion
10
+ # return an array of symbols with the platforms like :iphone and :ipad.
11
+ #
12
+ module TargetedDeviceFamily
13
+ extend self
14
+
15
+ #
16
+ # @param [String] value convert the comma-delimited list of platforms
17
+ # @return [Array<Symbol>] the platform names supported.
18
+ #
19
+ def open(value)
20
+ value.to_s.split(",").map do |platform_number|
21
+ platforms[platform_number]
22
+ end
23
+ end
24
+
25
+ #
26
+ # @param [Array<String>] value convert the array of platform names
27
+ # @return [String] the comma-delimited list of numeric values representing
28
+ # the platforms.
29
+ #
30
+ def save(value)
31
+ Array(value).map do |platform_name|
32
+ platforms.map {|number,name| number if name.to_s == platform_name.to_s.downcase }
33
+ end.flatten.compact.join(",")
34
+ end
35
+
36
+ private
37
+
38
+ def platforms
39
+ { "1" => :iphone, "2" => :ipad }
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+ end