ห้องสมุด? คงที่? Dynamic? หรือกรอบงาน โครงการภายในโครงการอื่น


151

ฉันมีแอพ iOS ที่มีอยู่และต้องการเพิ่มโค้ดขนาดใหญ่ที่ฉันได้พัฒนาเป็นโปรเจ็กต์อื่นเพื่อให้ง่ายต่อการทดสอบ อันใหม่ที่เกี่ยวกับการบันทึกภาพไปยังบริการแชร์ต่าง ๆ เป็นต้นเนื่องจากรหัสการแชร์นั้นต้องการการทดสอบจำนวนมากและการอัพเดทในอนาคตฉันจึงสงสัยว่าวิธีที่ดีที่สุดในการรวมโค้ดอันนั้นไว้ในแอพที่ฉันมีอยู่

ฉันไม่รู้ว่าควรเป็นห้องสมุดแบบคงที่, ห้องสมุดแบบไดนามิกหรือกรอบงานและตรงไปตรงมาฉันไม่แน่ใจจริงๆว่าสิ่งที่แตกต่างคืออะไรหรือฉันควรทำอย่างไรกับมันและตั้งค่าใน Xcode

ทั้งหมดที่ฉันรู้คือฉันต้องการ / ต้องการแยกการทดสอบและอัปเดตแอปสำหรับรหัสการแชร์แยกต่างหากและให้แอปหลักใช้งานได้


คุณสามารถสร้างกรอบงานร่มซึ่งมีลักษณะคล้าย 'กรอบภายในกรอบ' stackoverflow.com/a/27638841/1582217
Mohd Iftekhar Qurashi

มีความเป็นไปได้ที่ซ้ำกันของวิธีการสร้างเฟรมเวิร์กใน iOS sdk
Mohd Iftekhar Qurashi

คำตอบ:


204

ก่อนอื่นคำจำกัดความทั่วไป (เฉพาะสำหรับ iOS):

ห้องสมุดคง - หน่วยของรหัสที่เชื่อมโยงในเวลารวบรวมซึ่งจะไม่เปลี่ยนแปลง

อย่างไรก็ตามไลบรารีคงที่ของ iOS ไม่ได้รับอนุญาตให้มีรูปภาพ / เนื้อหา (รหัสเท่านั้น) คุณจะได้รับรอบความท้าทายนี้โดยใช้กำสื่อว่า

ที่ดีกว่าหมายอย่างเป็นทางการเพิ่มเติมสามารถพบได้ในวิกิพีเดียที่นี่

ห้องสมุดแบบไดนามิก - หน่วยของรหัสและ / หรือสินทรัพย์ที่เชื่อมโยง ณ รันไทม์ที่อาจมีการเปลี่ยนแปลง

อย่างไรก็ตามอนุญาตให้ Apple เท่านั้นสร้างไลบรารีแบบไดนามิกสำหรับ iOS คุณไม่ได้รับอนุญาตให้สร้างสิ่งเหล่านี้เนื่องจากจะทำให้แอปของคุณถูกปฏิเสธ (ดูนี้โพสต์ SO อื่น ๆ สำหรับการยืนยันและการให้เหตุผลดังกล่าว)

Software Framework - ชุดของโค้ดที่คอมไพล์ซึ่งทำให้งานสำเร็จ ... ดังนั้นคุณสามารถมีเฟรมเวิร์กแบบสแตติกหรือเฟรมเวิร์แบบไดนามิกซึ่งโดยทั่วไปแล้วจะเป็นเพียงเวอร์ชันคอมไพล์ข้างต้น

ดูWiki ใน Software Frameworkสำหรับรายละเอียดเพิ่มเติม

ดังนั้นใน iOS ตัวเลือกเดียวของคุณก็คือการใช้ static library หรือ static framework (ความแตกต่างหลักคือการที่ static framework ถูกแจกจ่ายเป็น.aไฟล์ที่คอมไพล์บ่อยที่สุดในขณะที่ static library อาจถูกรวมเป็น subproject - คุณสามารถเห็น รหัสทั้งหมด - ซึ่งถูกคอมไพล์ก่อนและ.aไฟล์ผลลัพธ์ของมันถูกใช้เป็นการอ้างอิงโดยโครงการ)

ตอนนี้เรามีความชัดเจนเกี่ยวกับเงื่อนไขเหล่านี้แล้วการตั้งค่าไลบรารีแบบคงที่และชุดสื่อสนับสนุนสำหรับ iOS นั้นไม่ใช่เรื่องยากเกินไปและมีบทเรียนมากมายเกี่ยวกับวิธีการดังกล่าว โดยส่วนตัวฉันจะแนะนำอันนี้:

https://github.com/jverkoey/iOS-Framework

นี่เป็นแนวทางที่ตรงไปตรงมาและไม่มีข้อเสียในการจัดการกับ "ไลบรารีคงที่ปลอม" ... ลองดูข้อมูลเพิ่มเติม ...

เมื่อคุณสร้างห้องสมุดแบบคงที่ของคุณแล้วมันก็ง่ายเหมือนการรวมเป็นsubmoduleภายใน Git เพื่อใช้กับโครงการต่างๆ

โชคดี.

แก้ไข

เกี่ยวกับโครงการย่อยภายในโครงการเท่าที่ฉันรู้เพื่อให้การทำงาน / คอมไพล์อย่างถูกต้องคุณจำเป็นต้องตั้งค่าคอมไพล์เชนที่โปรเจ็กต์ย่อยถูกคอมไพล์ก่อนซึ่งสร้าง.aไฟล์เฟรมเวิร์กแบบสแตติกที่ใช้เป็นการอ้างอิง โดยโครงการ

ต่อไปนี้เป็นบทช่วยสอนที่มีประโยชน์ซึ่งพูดถึงเรื่องนี้:

http://www.cocoanetics.com/2011/12/sub-projects-in-xcode/

แก้ไข 2

ตั้งแต่ iOS 8 ตอนนี้ Apple อนุญาตให้นักพัฒนาสร้างเฟรมเวิร์กแบบไดนามิก! (หมายเหตุ: แอปของคุณต้องมีเป้าหมายขั้นต่ำของ iOS 8 เพื่อรวมเฟรมเวิร์กแบบไดนามิก ... ไม่อนุญาตการย้ายกลับ)

สิ่งนี้ถูกเพิ่มเป็นเทมเพลตโครงการใหม่ ใน Xcode 6.1 สามารถดูได้ที่:

New Project -> iOS -> Framework & Library -> Cocoa Touch Framework

จนถึงตอนนี้ดูเหมือนว่าโครงการย่อยเป็นสิ่งที่ฉันต้องการและบทความนั้นสมบูรณ์แบบ ฉันสังเกตเห็นผลข้างเคียงที่แปลกประหลาดอย่างหนึ่ง: โครงการย่อยที่ฉันลากเข้าไปในโครงการหลักของฉันก็มีรหัสการทดสอบของฉัน (viewcontroller และปลายปากกา appdelegate ฯลฯ ) และฉันแน่ใจว่ามีเพียงคลาสที่ฉันต้องการใช้ใน มีการตรวจสอบโครงการหลักที่จะใช้ในไลบรารีแบบคงที่ แต่ด้วยเหตุผลบางอย่างเมื่อฉันไปทำสิ่งที่แนบมากับไฟล์ปลายปากกาของโครงการหลักของฉันมันก็แสดงให้เห็นถึงช่องทางและการกระทำจากโครงการย่อยของฉัน สิ่งนี้อาจนำไปสู่ความสับสนอย่างแน่นอน เคล็ดลับใด ๆ ในการกำจัดเหล่านั้น? ขอบคุณ!
pizzafilms

โปรเจ็กต์แบบไดนามิกสามารถถูกลากและวางลงในโปรเจ็กต์แบบสแตติกทำให้เป็นโปรเจ็กต์แบบสแตติกหรือไม่? ฉันสับสนจริงๆการชี้แจงบางอย่างก็ยอดเยี่ยมจริง ๆ ! ขอบคุณล่วงหน้า :-)
Ravindranath Akila

1
@ JRG-Developer การย้ายเฟรมเวิร์กไดนามิกกลับมาทำได้ถ้าคุณทำตามกฎบางอย่าง: developer.apple.com/library/prerelease/ios/documentation/…
klefevre

เป็นไปได้หรือไม่ที่จะกำหนดเป้าหมายขั้นต่ำที่ต่ำกว่าและทำให้ห้องสมุดเป็นทางเลือก
kukudas

1. คุณสามารถรวมตัวอย่างที่รู้จักกันดีของห้องสมุดแบบคงที่, ห้องสมุดแบบไดนามิกกรอบ? 2. คุณสามารถให้ตัวอย่างของตำแหน่งที่คุณต้องทำเช่นนั้นได้หรือไม่? 3. อยากรู้อยากเห็นความแตกต่างระหว่างพ็อดและไลบรารีคงที่คืออะไร?
น้ำผึ้ง

30

รูปแบบไฟล์ Mach-O (วัตถุเครื่อง - .o)

ในโลก iOS ไฟล์ต้นฉบับทุกไฟล์จะถูกแปลงเป็นไฟล์ออบเจ็กต์ - ABI [เกี่ยวกับ]ไฟล์ Mach-O [เกี่ยวกับ]ซึ่งจะถูกรวมไว้ในชุดไฟล์ปฏิบัติการขั้นสุดท้าย (เช่นแอปพลิเคชันกรอบงาน ... ) ไฟล์ (เช่นห้องสมุด ... ) และพฤติกรรมของมันถูกกำหนดโดยMach-O type[เกี่ยวกับ]

Packageเป็นไดเรกทอรีที่ behavious ตัวเองเป็นแฟ้ม opaque file- มันถูกสร้างขึ้นสำหรับประสบการณ์ของผู้ใช้ที่จะทำการเปลี่ยนแปลงโครงสร้างภายในที่ทำให้เกิดพฤติกรรมของโปรแกรมที่ไม่สามารถคาดการณ์ได้ แพคเกจที่ใช้ในการหรือกับDocument Package Bundleคุณสามารถใช้Show Package Contentsใน Finder

Bundleเป็นไดเรกทอรีที่มีโครงสร้างเฉพาะในการจัดระเบียบไบนารี (รหัสที่สามารถใช้งานได้) และทรัพยากรสำหรับรหัสนั้น (เช่นอิมเมจ, ไส้ปากกา ... ) บันเดิลมีไฟล์Info.plist[เกี่ยวกับ] Bundle ถูกสร้างขึ้นสำหรับประสบการณ์นักพัฒนา นอกจากนี้ยังสามารถบรรจุ บันเดิลมีหลายประเภท:

  • application bundle - Application target
  • framework bundleและversioned bundleเป็นประเภทย่อย -Framework Target
  • loadable bundle(aka plug-in bundle) - Bundle target(ชุดทดสอบ UI, ชุดทดสอบหน่วย)
  • อื่น ๆ ( dSYM[เกี่ยวกับ]ชุดข้อมูล)

Application- .ipa, .app[เกี่ยวกับ] - packaged application bundle- โปรแกรมที่เปิดใช้งานได้

Tests- packaged loadable bundleซึ่งใช้ในการทดสอบไบนารี สถาปัตยกรรมปลั๊กอินช่วยให้เราสามารถเพิ่มฟังก์ชั่นใหม่ (กรณีทดสอบ) เป็นโมดูลแยกลงในไบนารีที่มีอยู่

ห้องสมุดและกรอบงาน

Martin Fowler บน InversionOfControl

Library เป็นชุดของฟังก์ชั่นที่คุณสามารถโทรหาได้ในปัจจุบันมักจะจัดเป็นคลาส การโทรแต่ละครั้งจะทำงานและส่งคืนการควบคุมให้กับลูกค้า

Framework รวบรวมการออกแบบที่เป็นนามธรรมพร้อมกับมีพฤติกรรมมากขึ้นในการใช้งานคุณจำเป็นต้องแทรกพฤติกรรมของคุณลงในสถานที่ต่าง ๆ ในกรอบทั้งโดยการทำคลาสย่อยหรือโดยการเสียบในชั้นเรียนของคุณเอง รหัสของเฟรมเวิร์กจะเรียกรหัสของคุณที่จุดเหล่านี้ ตัวควบคุมหลักของโปรแกรมกลับด้านย้ายจากคุณไปที่เฟรมเวิร์ก (การกลับกันของการควบคุม)

ไลบรารีและกรอบงานบน iOS

Libraryเป็นชุดของไฟล์วัตถุ Mach-O [ตรวจสอบคงที่หรือแบบไดนามิก]รวบรวมสำหรับสถาปัตยกรรมอย่างน้อยหนึ่ง

Static library- .a(หรือที่รู้จักกันว่าไลบรารีเก็บถาวรแบบคงที่, ไลบรารีที่เชื่อมโยงแบบคงที่ที่มีการแชร์[doc] ) - เมื่อคุณเพิ่มลงในแอปพลิเคชันของคุณสแตติกเกอร์ลิงก์ระหว่างการรวบรวมจะรวมไฟล์วัตถุจากไลบรารีและจัดเก็บ ไฟล์. ข้อเสียคือไฟล์เอาต์พุตขนาดใหญ่

จาก Xcode 9.0 สนับสนุนไลบรารีแบบคงที่ Swift

Dynamic library- .dylib(aka ไลบรารีที่ใช้ร่วมกันแบบไดนามิกวัตถุที่แชร์ห้องสมุดที่เชื่อมโยงแบบไดนามิก[doc] ) มีการเชื่อมโยงแบบไดนามิกกับแอปปฏิบัติการที่โหลดหรือรันไทม์ของแอปแต่ไม่ได้คัดลอกลงใน ในทางปฏิบัติแพคเกจของแอปจะมีโฟลเดอร์ Frameworks พร้อม.dylibไฟล์ ทั้งหมด iOS และ MacOS ระบบdynamicห้องสมุด ข้อเสียคือเวลาเปิดตัวช้าเนื่องจากไลบรารีไดนามิกทั้งหมดควรถูกคัดลอกและเชื่อมโยง

[การเชื่อมโยงแบบคงที่เทียบกับแบบไดนามิก]

Text-based stub library- .tbd[เกี่ยวกับ]เป็นส่วนย่อยของข้อความdynamic libraryซึ่งตั้งอยู่บนอุปกรณ์เป้าหมาย ดังนั้นคุณไม่ควรจัดทำไลบรารีแบบไดนามิกในบันเดิลของคุณ มันมีผลกระทบขนาด

Frameworkอาคาbinary framework- .frameworkเป็นnot packaged framework bundle(เพื่อให้นักพัฒนาสามารถดูส่วนหัวและทรัพยากรได้อย่างง่ายดาย) ซึ่งมีstatic or dynamicไลบรารีที่คอมไพล์ไฟล์ส่วนหัวและทรัพยากร

Static frameworkมีstatic libraryแพ็กเกจที่มีรีซอร์ส

Dynamic frameworkมีdynamic libraryและทรัพยากร นอกจากนั้นเฟรมเวิร์กแบบไดนามิกยังสามารถรวมไลบรารีไดนามิกเดียวกันในเวอร์ชันต่างๆในบันเดิลเดียว ( versioned bundle)

[เฟรมคงที่เทียบกับไดนามิก]

Embedded frameworkเป็นdynamic frameworkกล่องแซนด์บ็อกซ์ของแอพ ประเภทนี้ถูกสร้างขึ้นครั้งแรกของทั้งหมดสำหรับการขยายรหัสหุ้นสามัญและทรัพยากร ใช้ได้เมื่อเป้าหมายการปรับใช้คือ iOS 8+

Umbrella framework [เป้าหมายรวม]เป็นกรอบงานที่มีกรอบงานอื่น ๆ มันไม่ได้สนับสนุนอย่างเป็นทางการบน iOS และนั่นคือเหตุผลว่าทำไมจึงไม่แนะนำสำหรับนักพัฒนาเพื่อสร้างพวกเขา[เอกสารอย่างเป็นทางการ] ในความเป็นจริงมันเป็นชุดของเฟรมเวิร์กย่อย (หรือ Nested Frameworks) เมื่อคุณสร้างเฟรมเวิร์กที่มีการพึ่งพาผู้บริโภค (เช่นแอพ) จะรับผิดชอบในการเพิ่มการพึ่งพานี้พร้อมกับเฟรมเวิร์กของคุณลงในโครงการ ในฐานะนักพัฒนาเป็นเรื่องปกติที่จะพยายามหาวิธีถ่ายโอนหน้าที่นี้จากผู้บริโภคไปยังของคุณ เป็นผลให้คุณคิดว่าUmbrella frameworkเป็นการช่วยเหลือ แต่มักจะนำไปสู่ปัญหาร้ายแรงกับการจัดการเวอร์ชันและความซับซ้อนในการสร้างและสนับสนุน

Fake Framework- เป็นผลมาจากการดำเนินงานเฉพาะภายใต้static libraryการสร้างมัดที่มีส่วนขยายที่จะประพฤติตัวเองเป็น.framework dynamic frameworkเทคนิคนี้ใช้เมื่อ Xcode ไม่สนับสนุนการสร้างเฟรมเวิร์กเนื่องจากไม่มีเท็มเพลตเฟรมเวิร์ก หนึ่งในสำนึกของกรอบปลอม ด้วย Xcode 6 Apple ได้เพิ่มการสนับสนุนเฟรมเวิร์ก iOS

Modular Framework[เกี่ยวกับ] -@importเป็นกรอบซึ่งมี.modulemapไฟล์อยู่ภายใน โมดูลสามารถมี submodules Modular Frameworkประโยชน์หลักคือการที่คุณประหยัดเวลาในการสร้างด้วย

Universal Library or Framework(aka Fat) [lipo] [เป้าหมายรวม]มีสถาปัตยกรรมหลายแห่ง ตัวอย่างเช่นงานสร้างของคุณควรสนับสนุน arch บางอย่างที่คุณสามารถควบคุมผ่านBuild Active Architecture Only [ONLY_ACTIVE_ARCH]

Dependency[เกี่ยวกับ]คุณสามารถใช้รหัสบุคคลที่สามเป็นส่วนหนึ่งของเป้าหมายได้ ช่วยให้คุณสามารถใช้รหัสจากแหล่งที่มาจำนวนมากเช่น - โครงการอื่นโครงการในพื้นที่ทำงานเดียวกันเป้าหมายอื่นห้องสมุดกรอบงาน ฯลฯ

วิธีสร้างและใช้ห้องสมุดแบบคงที่:

วิธีสร้างและใช้ Dynamic Framework [เปลี่ยนเป็นสแตติก]

[Xcode Build System]
[ส่วนประกอบ Xcode]
[Dynamic linker]


1
ในบทช่วยสอน Swift หลายอย่างที่กล่าวถึงว่า Objective C ไม่รองรับไลบรารีแบบไดนามิกซึ่งเป็นไปตามที่ swift รองรับ [ altexsoft.com/blog/engineering/ ...... ] แต่อย่างที่ฉันรู้ว่า i OS8 เป็นต้นไป Objctive C รองรับไลบรารีแบบไดนามิก คุณช่วยอธิบายเรื่องนี้ได้ไหม
pratima

@pratima คุณสามารถสร้างเฟรมเวิร์กแบบไดนามิกบน Objective-C สำหรับ iOS
yoAlex5

1
"กรอบงานแบบคงที่ประกอบด้วยไลบรารีแบบคงที่ที่บรรจุด้วยทรัพยากร" คำจำกัดความนี้มาจากไหน AFAK ขั้นตอนการสร้าง "Copy Bundle Resources" ของเฟรมเวิร์กไม่ทำงานเช่นเดียวกับไลบรารีแบบสแตติก อะไรคือข้อแตกต่างระหว่าง static framework กับ static library?
toshi0383

@ toshi0383 คุณหาวิธีผสานไลบรารีแบบคงที่ (.a) และเป็นแหล่งข้อมูล (.bundle) ในกรอบงานเดียวที่เราสามารถแจกจ่ายให้ผู้บริโภคได้หรือไม่?
user121095

2

คุณยังสามารถสร้างไฟล์. Podspec สำหรับ CocoaPods ( http://guides.cocoapods.org/making/private-cocoapods.html#1.-create-a-private-spec-repo ) และใช้มันเหมือนกับพ็อดอื่น ๆ ที่มี ความแตกต่างเพียงอย่างเดียวว่าเป็นพ็อดส่วนตัวของคุณและไม่สามารถมองเห็นได้จากโลกภายนอก (ฉันไม่แน่ใจว่าจะเกิดอะไรขึ้นหากพ็อดของคุณควรสร้างโมเดล CoreData แต่นั่นไม่ใช่กรณีดังที่ฉันเข้าใจ)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.