Section 6/151 menit

6. Hybrid Project: Menggunakan Keduanya Bersamaan

6. Hybrid Project: Menggunakan Keduanya Bersamaan

Kapan Butuh Hybrid?

Situasi yang paling umum membutuhkan hybrid CocoaPods + SPM:

  1. Library yang belum tersedia di SPM — Firebase, Google Mobile Ads, beberapa Mapbox SDK masih CocoaPods-primary
  2. Migrasi bertahap — tidak bisa migrate semua sekaligus, butuh periode transisi
  3. Legacy project — CocoaPods untuk dependencies lama, SPM untuk yang baru
  4. Binary-only SDK — vendor provide CocoaPods only, tidak ada SPM support

Setup Hybrid Project

swift
Struktur project hybrid:
MyApp/
├── MyApp.xcworkspace      ← dibuka CocoaPods (BUKAN .xcodeproj)
├── MyApp.xcodeproj        ← project asli, berisi SPM package refs
├── Podfile                ← CocoaPods config
├── Podfile.lock           ← CocoaPods lock
├── Package.swift          ← SPM packages (jika app sebagai package)
└── Pods/                  ← generated CocoaPods

Penting: Untuk hybrid, kamu membuka .xcworkspace (bukan .xcodeproj). SPM dependencies dikelola di dalam .xcodeproj via Xcode's built-in SPM support.

Cara Menambahkan SPM ke Proyek CocoaPods yang Ada

swift
# 1. Buka MyApp.xcworkspace (BUKAN .xcodeproj!)
#    File > Add Package Dependencies...
#    Masukkan URL package: https://github.com/Alamofire/Alamofire
#    Pilih version rule → Add Package

# 2. Xcode akan:
#    - Tambahkan entry di MyApp.xcodeproj/project.pbxproj
#    - Buat MyApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

# 3. Commit file yang perlu:
git add MyApp.xcodeproj/project.pbxproj
git add "MyApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved"

Podfile Hybrid: Hindari Konflik dengan SPM

swift
# Podfile untuk hybrid project

platform :ios, '16.0'

# KRITIS untuk hybrid: gunakan static frameworks dari CocoaPods
# Ini menghindari konflik linking dengan SPM dynamic frameworks
use_frameworks! :linkage => :static

install! 'cocoapods',
  :deterministic_uuids => false

target 'MyApp' do
  # Hanya pods yang TIDAK tersedia di SPM
  pod 'Firebase/Analytics'
  pod 'Firebase/Crashlytics'
  pod 'GoogleMobileAds', '~> 11.0'
  
  # Library internal yang belum dimigrate ke SPM
  pod 'MyLegacyAnalytics', :path => '../SDKs/MyLegacyAnalytics'
  
  # SPM dependencies dikelola via Xcode UI, TIDAK di Podfile
  # Jangan tambahkan Alamofire di sini jika sudah ada di SPM
  
  target 'MyAppTests' do
    inherit! :search_paths
  end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
      
      # Untuk hybrid dengan static frameworks, set ini:
      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'NO'
    end
  end
end

Menghindari Duplikasi Dependencies di Hybrid

swift
# ❌ BAHAYA: library yang sama di CocoaPods DAN SPM
# Podfile:
pod 'Alamofire', '~> 5.9'
# DAN di Xcode SPM: https://github.com/Alamofire/Alamofire

# Ini menyebabkan:
# - Duplicate symbols linker error
# - Binary bloat (dua copy Alamofire)
# - Runtime crash yang sulit di-debug

# ✅ AMAN: pilih salah satu sumber untuk setiap library
# Buat daftar di DEPENDENCIES.md:
# CocoaPods only:
#   - Firebase (Analytics, Crashlytics, Messaging)
#   - GoogleMobileAds
# SPM only:
#   - Alamofire
#   - Kingfisher
#   - SwiftLint (sebagai plugin)

Package.resolved di Hybrid Project

Di hybrid project, ada DUA Package.resolved:

swift
# 1. Untuk app (dikelola Xcode):
MyApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

# 2. Untuk package standalone (jika ada Package.swift di root):
Package.resolved  (di root)

# Keduanya harus di-commit ke Git!