Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
RubyでiOSアプリをビルドしよう
henteko
August 25, 2016
Technology
0
1.1k
RubyでiOSアプリをビルドしよう
iOSDC 2016 前夜祭
henteko
August 25, 2016
Tweet
Share
More Decks by henteko
See All by henteko
henteko
1
1.4k
henteko
0
330
henteko
0
120
henteko
1
96
henteko
1
1.8k
henteko
0
2.3k
henteko
1
1.8k
henteko
0
1.8k
henteko
0
220
Other Decks in Technology
See All in Technology
nihonbuson
2
1.9k
masashible
0
110
humank
0
220
ocise
0
170
ishiayaya
PRO
0
340
ama_ch
0
3.7k
hamadakoji
1
1.1k
kentaro
1
430
papix
0
140
suzukiry
0
210
redhatopenshift
0
320
hsano
0
130
Featured
See All Featured
addyosmani
1348
190k
frogandcode
127
20k
lauravandoore
437
28k
jmmastey
9
540
bermonpainter
342
26k
kneath
294
39k
jakevdp
774
200k
matthewcrist
73
7.5k
mongodb
23
3.8k
scottboms
251
11k
sstephenson
144
12k
jasonvnalue
82
8.1k
Transcript
3VCZͰJ04ΞϓϦΛ Ϗϧυ͠Α͏ J04%$લࡇ Μͯ͜
%FQMPZ(BUF 5XJUUFS!IFOUFLP ࣗݾհ Μͯ͜
3VCZͰJ04ΞϓϦΛ Ϗϧυ͢Δख๏
EHEFQMPZ
None
EHBEEEFWJDFT
BEEEFWJDFTҎલ
Ϣʔβʔ͕ΞϓϦͷςετʹࢀՃ ͜ͷ࣌Ͱ·ͩΞϓϦͷΠϯετʔϧ͕ग़དྷͳ͍ 6%*%͕։ൃऀʹΘΔ खಈͰ%FW$FOUFSʹొ্ͯ͛͠͠ ΞϓϦΠϯετʔϧͰ͖ΔΑ͏ʹ
BEEEFWJDFT͏ͱ
Ϣʔβʔ͕ΞϓϦͷςετʹࢀՃ ͜ͷ࣌Ͱ·ͩΞϓϦͷΠϯετʔϧ͕ग़དྷͳ͍ BEEEFWJDFTΛୟ͚ͩ͘ ΞϓϦΠϯετʔϧͰ͖ΔΑ͏ʹ
BEEEFWJDFTTFSWFS
Ϣʔβʔ͕ΞϓϦͷςετʹࢀՃ ͜ͷ࣌Ͱ·ͩΞϓϦͷΠϯετʔϧ͕ग़དྷͳ͍ ࣗಈͰΞϓϦ͕Ϗϧυ͞ΕΔ ͙͢ʹΞϓϦΠϯετʔϧͰ͖ΔΑ͏ʹ ਆ
None
3VCZ
ओʹ͍ͯ͠Δ͜ͱ 9DPEFϓϩδΣΫτͷղੳ ϩʔΧϧͷ1SPWJTJPOJOH1SPpMFͷղੳ J04ΞϓϦͷϏϧυ
9DPEFϓϩδΣΫτղੳ #VOEMF*EFOUJpFSͷऔಘ ྫDPNIFOUFLPMPPQFS ઃఆ͍ͯ͠Δ1SPWJTJPOJOH1SPpMFͷಛఆ
9DPEFϓϩδΣΫτղੳ Ϗϧυ͢Δ4DIFNFΛಛఆ͢Δ ͦͷ4DIFNFͷYDTDIFNFϑΝΠϧΛऔಘ͢Δ YDTDIFNFϑΝΠϧ͔Β5BSHFU/BNFΛऔಘ͢Δ 9DPEFϓϩδΣΫτΛऔಘ͢Δ
4DIFNFऔಘ Ϗϧυରͷ4DIFNFΛऔಘ͢Δ
None
4DIFNFऔಘ HZN GBTUMBOF Λ͍ͬͯΔ 1 def target_scheme 2 config =
FastlaneCore::Configuration.create( 3 Gym::Options.available_options, 4 { 5 workspace: XCODE_WORKSPACE_PATH 6 } 7 ) 8 project = FastlaneCore::Project.new(config) 9 project.select_scheme 10 project.options[:scheme] 11 end
YDTDIFNFϑΝΠϧऔಘ औಘͨ͠4DIFNF͔ΒYDTDIFNFϑΝΠϧΛऔಘ ͢Δ ී௨ʹσΟϨΫτϦΛ୳ࡧ BQQYDPEFQSPKYDVTFSEBUBVTFSYDVTFSEBUBE YDTDIFNFTUBSHFU@TDIFNFYDTDIFNF
1 def find_xcschemes(target_scheme) 2 Dir[ 3 File.join( 4 XCODE_PROJECT_PATH, 5
'xcuserdata', 6 '*.xcuserdatad', 7 'xcschemes', 8 '*.xcscheme' 9 ) 10 ].reject do |scheme| 11 target_scheme != 12 File.basename(scheme, '.xcscheme') 13 end 14 end
5BSHFU/BNFͷऔಘ औಘͨ͠YDTDIFNFϑΝΠϧ͔ΒUBSHFUOBNFΛ औಘ͢Δ YDPEFQSPKΛ͍ͬͯΔ
1 xs = Xcodeproj::XCScheme.new(scheme_file) 2 target_name = xs. 3 profile_action.
4 buildable_product_runnable. 5 buildable_reference. 6 target_name
9DPEFϓϩδΣΫτऔಘ ϓϩδΣΫτΛऔಘ͢Δ 1 project = Xcodeproj::Project.open( 2 XCODE_PROJECT_PATH) 3 project
= project. 4 native_targets. 5 reject{|target| target.name != target_name}. 6 first
#VJME$POpHVSBUJPO ֤#VJMEDPOpHVSBUJPO͝ͱͷઃఆΛऔಘͰ͖Δ 1 def target_build_configuration(target_project) 2 target_project. 3 build_configuration_list. 4
build_configurations. 5 reject{|conf| conf.name != 'Release'}. 6 first 7 end
֤ઃఆΛऔಘ #VOEMF*EFOUJpFSͳͲΛऔಘͰ͖Δ 1 target_project. 2 product_name 3 target_build_configuration. 4 build_settings['PRODUCT_BUNDLE_IDENTIFIER']
5 target_build_configuration. 6 build_settings['PROVISIONING_PROFILE']
1SPWJTJPOJOH1SPpMFղੳ ϩʔΧϧʹ͋Δ1SPWJTJPOJOH1SPpMFΛղੳ͢Δ 1SPWJTJPOJOH1SPpMFͷূ໌ॻ͕.BDʹΠϯετʔ ϧ͞Ε͍ͯΔ͔ݟΔ
QSPpMFͷऔಘ NPCJMFQSPWJTJPOϑΝΠϧΛऔಘ͢Δ d-JCSBSZ.PCJMF%FWJDF1SPWJTJPOJOH1SPpMFT ʹଘࡏ͍ͯ͠Δ
1 def load_profile_paths 2 profiles_path = 3 File.expand_path("~") + 4
"/Library/MobileDevice/Provisioning 5 Profiles/*.mobileprovision" 6 Dir[profiles_path] 7 end
QSPpMFΛղੳ PQFOTTMͱQMJTUͰղੳ͢Δ 1 def profile_to_plist(profile_path) 2 File.open(profile_path) do |profile| 3
asn1 = OpenSSL::ASN1.decode(profile.read) 4 plist_str = asn1.value[1].value[0].value[2]. 5 value[1].value[0].value 6 plist = Plist.parse_xml plist_str. 7 force_encoding('UTF-8') 8 plist['Path'] = profile_path 9 return plist 10 end 11 end
66*% ༗ޮظݶ "QQMJDBUJPO*EFOUJpFS 5FBNOBNF 1 profile['UUID'] 2 profile['ExpirationDate'] 3 if
profile['Entitlements'] 4 profile['Entitlements']['application- 5 identifier'] 6 end 7 profile['TeamName']
"EIPD͔Ͳ͏͔ 1SPWJTJPOJOH1SPpMF͕"EIPD༻͔Ͳ͏͔֬ೝͰ͖ Δ 1SPWJTJPOT"MM%FWJDFT͕͋Δͱ*O)PVTF༻ 1 def adhoc?(profile) 2 !profile['Entitlements']['get-task-allow'] &&
3 profile['ProvisionsAllDevices'].nil? 4 end
ূ໌ॻͷ֬ೝ .BDʹ1SPWJTJPOJOH1SPpMFͷূ໌ॻ͕Πϯετʔ ϧ͞Ε͍ͯΔ͔Ͳ͏͔ͷ֬ೝ Πϯετʔϧ͞Ε͍ͯͳ͍ͱJ04ΞϓϦͷϏϧυʹ ࣦഊ͢Δ
ূ໌ॻҰཡऔಘ TFDVSJUZίϚϯυΛ͏ 1 def installed_certificates 2 available = `security find-identity
-v -p 3 codesigning` 4 certificates = [] 5 available.split("\n").each do |current| 6 next if current.include? "REVOKED" 7 certificates << current 8 end 9 10 certificates 11 end
J1IPOF%JTUSJCVUJPO༻Λऔಘ J1IPOF%JTUSJCVUJPO)0(&ͳͷ͚ͩΛऔಘ 1 def installed_distribution_certificate_ids 2 certificates = installed_certificates() 3
ids = [] 4 certificates.each do |current| 5 next unless current.match(/iPhone 6 Distribution:/) 7 (ids << current.match(/.*\) (.*) \".*/)[1]) 8 end 9 10 ids 11 end
Πϯετʔϧ֬ೝ PQFOTTMͰ1SPpMFͷJEΛ֬ೝ ΠϯετʔϧࡁΈͷJEʹͦΕؚ͕·Ε͍ͯͨΒΠϯ ετʔϧࡁΈ
1 def installed_certificate?(profile_path) 2 profile = profile_to_plist profile_path 3 certs
= profile['DeveloperCertificates'].map 4 do |cert| 5 certificate_str = cert.read 6 certificate = OpenSSL::X509::Certificate. 7 new certificate_str 8 id = OpenSSL::Digest::SHA1.new(certificate. 9 to_der).to_s.upcase 10 installed_distribution_certificate_ids. 11 include?(id) 12 end 13 certs.include?(true) 14 end
J04ΞϓϦϏϧυ HZN GBTUMBOF Λ͏ ಛʹԿߟ͑ͳͯ͘ɺࠓ·ͰಘͨใͰϏϧυ͕ Ͱ͖Δ
1 EXPORT_METHOD = 'ad-hoc' 2 WORKSPACE = '/path/to/ios-app/app.xcodeproj' 3 CONFIGURATION
= 'Release' 4 SCHEME = 'target_scheme' 5 CODESIGNING_IDENTITY = 'iPhone Distribution: 6 HOGE (xxxxxxxxx)' 7 8 def build 9 values = { 10 export_method: EXPORT_METHOD, 11 workspace: WORKSPACE, 12 configuration: CONFIGURATION, 13 scheme: SCHEME, 14 codesigning_identity: 15 CODESIGNING_IDENTITY 16 } 17 v = FastlaneCore::Configuration.create(Gym:: 18 Options.available_options, values) 19 20 File.expand_path(Gym::Manager.new.work(v)) 21 end
·ͱΊ 3VCZͰ9DPEFϓϩδΣΫτͷղੳ͕Ͱ͖·͢ 1SPWJTJPOJOH1SPpMFͷղੳ ϏϧυGBTUMBOFܦ༝ͰYDPEFCVJMEΛୟ͘ͷ͕ ͓͢͢Ί IUUQTHJUIVCDPNIFOUFLP JPTED@@TBNQMF
EHΑΖ͘͠Ͷʂ ιʔείʔυ(JUIVCͰެ։த