Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RubyでiOSアプリをビルドしよう
Search
henteko
August 25, 2016
Technology
1.6k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RubyでiOSアプリをビルドしよう
iOSDC 2016 前夜祭
henteko
August 25, 2016
More Decks by henteko
See All by henteko
Gitが世界を制した理由は「革新」ではなく「運用」だった
henteko
0
70
AIが書いたコードをAIが検証する!自律的なモバイルアプリ開発の実現
henteko
1
1.3k
エンジニア経営者がハマりがちな罠
henteko
1
380
データ分析基盤を構築してみた
henteko
1
490
Unity Shader Graphで魔法陣を作ってみた
henteko
1
7.5k
ML-Agentsの簡単な環境構築
henteko
0
1.3k
2012TeRes11月部会
henteko
0
170
技術系同人誌執筆のすゝめ
henteko
1
160
ipaファイルの中身を 覗いてみよう
henteko
1
2.4k
Other Decks in Technology
See All in Technology
【CEDEC2026】Creative Approaches to Localizing the Dialects and Unique Speech of Umamusume: Pretty Derby Characters in English
cygames
PRO
3
18k
AWS ネットワーク構築でハマった(ハマりかけた) 5選とそこから得た教訓
nagisa53
4
210
強化学習「理論」入門
enakai00
3
3.6k
事業価値と Engineering 2026年度版
recruitengineers
PRO
49
23k
モノリス Rails でも日中に rails db:migrate を走らせたい! / Daytime rails db:migrate on Monolithic Rails!
euglena1215
4
580
第3回しろおびセキュリティスポンサーセッション
log0417
0
180
JavaScript 研修 (2026)
recruitengineers
PRO
2
540
AIペネトレーションテスト・ セキュリティ検証「AgenticSec」紹介資料
laysakura
2
9k
Sets in Go
ramalho
1
570
2026-08-05 IBM Z開発最前線!IBM Bob Premium Package for Zって何がすごいの?
yutanonaka
0
110
その“隠したつもり”が命取り ── 自前と平文をやめて「正解」に委ねる
kuroneko13
0
120
メルカリのグローバルアプリで挑んだ AlloyDB 運用と課題解決の実践記
hatappi
0
250
Featured
See All Featured
A Tale of Four Properties
chriscoyier
163
24k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
460
Building Applications with DynamoDB
mza
96
7.2k
エンジニアに許された特別な時間の終わり
watany
108
250k
GraphQLとの向き合い方2022年版
quramy
50
15k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
320
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
360
Facilitating Awesome Meetings
lara
57
7.1k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
56k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
The Language of Interfaces
destraynor
162
27k
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Ͱެ։த