Slide 1

Slide 1 text

3VCZͰJ04ΞϓϦΛ Ϗϧυ͠Α͏ J04%$લ໷ࡇ ΁Μͯ͜

Slide 2

Slide 2 text

%FQMPZ(BUF 5XJUUFS!IFOUFLP ࣗݾ঺հ ΁Μͯ͜

Slide 3

Slide 3 text

3VCZͰJ04ΞϓϦΛ Ϗϧυ͢Δख๏

Slide 4

Slide 4 text

EHEFQMPZ

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

EHBEEEFWJDFT

Slide 7

Slide 7 text

BEEEFWJDFTҎલ

Slide 8

Slide 8 text

Ϣʔβʔ͕ΞϓϦͷςετʹࢀՃ ͜ͷ࣌఺Ͱ͸·ͩΞϓϦͷΠϯετʔϧ͕ग़དྷͳ͍ 6%*%͕։ൃऀʹ఻ΘΔ खಈͰ%FW$FOUFSʹొ࿥্ͯ͛͠௚͠ ΞϓϦΠϯετʔϧͰ͖ΔΑ͏ʹ

Slide 9

Slide 9 text

BEEEFWJDFT࢖͏ͱ

Slide 10

Slide 10 text

Ϣʔβʔ͕ΞϓϦͷςετʹࢀՃ ͜ͷ࣌఺Ͱ͸·ͩΞϓϦͷΠϯετʔϧ͕ग़དྷͳ͍ BEEEFWJDFTΛୟ͚ͩ͘ ΞϓϦΠϯετʔϧͰ͖ΔΑ͏ʹ

Slide 11

Slide 11 text

BEEEFWJDFTTFSWFS

Slide 12

Slide 12 text

Ϣʔβʔ͕ΞϓϦͷςετʹࢀՃ ͜ͷ࣌఺Ͱ͸·ͩΞϓϦͷΠϯετʔϧ͕ग़དྷͳ͍ ࣗಈͰΞϓϦ͕Ϗϧυ͞ΕΔ ͙͢ʹΞϓϦΠϯετʔϧͰ͖ΔΑ͏ʹ ਆ

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

3VCZ

Slide 15

Slide 15 text

ओʹ͍ͯ͠Δ͜ͱ 9DPEFϓϩδΣΫτͷղੳ ϩʔΧϧͷ1SPWJTJPOJOH1SPpMFͷղੳ J04ΞϓϦͷϏϧυ

Slide 16

Slide 16 text

9DPEFϓϩδΣΫτղੳ #VOEMF*EFOUJpFSͷऔಘ ྫDPNIFOUFLPMPPQFS ઃఆ͍ͯ͠Δ1SPWJTJPOJOH1SPpMFͷಛఆ

Slide 17

Slide 17 text

9DPEFϓϩδΣΫτղੳ Ϗϧυ͢Δ4DIFNFΛಛఆ͢Δ ͦͷ4DIFNFͷYDTDIFNFϑΝΠϧΛऔಘ͢Δ YDTDIFNFϑΝΠϧ͔Β5BSHFU/BNFΛऔಘ͢Δ 9DPEFϓϩδΣΫτΛऔಘ͢Δ

Slide 18

Slide 18 text

4DIFNFऔಘ Ϗϧυର৅ͷ4DIFNFΛऔಘ͢Δ

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

YDTDIFNFϑΝΠϧऔಘ औಘͨ͠4DIFNF͔ΒYDTDIFNFϑΝΠϧΛऔಘ ͢Δ ී௨ʹσΟϨΫτϦ಺Λ୳ࡧ BQQYDPEFQSPKYDVTFSEBUBVTFSYDVTFSEBUBE YDTDIFNFTUBSHFU@TDIFNFYDTDIFNF

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

5BSHFU/BNFͷऔಘ औಘͨ͠YDTDIFNFϑΝΠϧ͔ΒUBSHFUOBNFΛ औಘ͢Δ YDPEFQSPKΛ࢖͍ͬͯΔ

Slide 24

Slide 24 text

1 xs = Xcodeproj::XCScheme.new(scheme_file) 2 target_name = xs. 3 profile_action. 4 buildable_product_runnable. 5 buildable_reference. 6 target_name

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

#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

Slide 27

Slide 27 text

֤ઃఆΛऔಘ #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']

Slide 28

Slide 28 text

1SPWJTJPOJOH1SPpMFղੳ ϩʔΧϧʹ͋Δ1SPWJTJPOJOH1SPpMFΛղੳ͢Δ 1SPWJTJPOJOH1SPpMFͷূ໌ॻ͕.BDʹΠϯετʔ ϧ͞Ε͍ͯΔ͔ݟΔ

Slide 29

Slide 29 text

QSPpMFͷऔಘ NPCJMFQSPWJTJPOϑΝΠϧΛऔಘ͢Δ d-JCSBSZ.PCJMF%FWJDF1SPWJTJPOJOH1SPpMFT ʹଘࡏ͍ͯ͠Δ

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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']

Slide 33

Slide 33 text

"EIPD͔Ͳ͏͔ 1SPWJTJPOJOH1SPpMF͕"EIPD༻͔Ͳ͏͔֬ೝͰ͖ Δ 1SPWJTJPOT"MM%FWJDFT͕͋Δͱ*O)PVTF༻ 1 def adhoc?(profile) 2 !profile['Entitlements']['get-task-allow'] && 3 profile['ProvisionsAllDevices'].nil? 4 end

Slide 34

Slide 34 text

ূ໌ॻͷ֬ೝ .BDʹ1SPWJTJPOJOH1SPpMFͷূ໌ॻ͕Πϯετʔ ϧ͞Ε͍ͯΔ͔Ͳ͏͔ͷ֬ೝ Πϯετʔϧ͞Ε͍ͯͳ͍ͱJ04ΞϓϦͷϏϧυʹ ࣦഊ͢Δ

Slide 35

Slide 35 text

ূ໌ॻҰཡऔಘ 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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

Πϯετʔϧ֬ೝ PQFOTTMͰ1SPpMFͷJEΛ֬ೝ ΠϯετʔϧࡁΈͷJEʹͦΕؚ͕·Ε͍ͯͨΒΠϯ ετʔϧࡁΈ

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

J04ΞϓϦϏϧυ HZN GBTUMBOF Λ࢖͏ ಛʹԿ΋ߟ͑ͳͯ͘΋ɺࠓ·Ͱಘͨ৘ใͰϏϧυ͕ Ͱ͖Δ

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

·ͱΊ 3VCZͰ9DPEFϓϩδΣΫτͷղੳ͕Ͱ͖·͢ 1SPWJTJPOJOH1SPpMFͷղੳ΋ Ϗϧυ͸GBTUMBOFܦ༝ͰYDPEFCVJMEΛୟ͘ͷ͕ ͓͢͢Ί IUUQTHJUIVCDPNIFOUFLP JPTED@@TBNQMF

Slide 42

Slide 42 text

EHΑΖ͘͠Ͷʂ ιʔείʔυ͸(JUIVCͰެ։த