SPM (Swift Package Manager) Swift इकोसिस्टम का एक अंतर्निर्मित पैकेज प्रबंधक है, जिसे Apple ने तृतीय-पक्ष लाइब्रेरीज़ को जोड़ने, बनाने और अपडेट करने के स्वचालन के लिए विकसित किया है। SPM संस्करण 3.0 (2016) से Swift कंपाइलर का हिस्सा रहा है और इसे अलग से स्थापित करने की आवश्यकता नहीं है। CocoaPods और Carthage के विपरीत, SPM सीधे कंपाइलर और Xcode के साथ एकीकृत होता है, जो इसे आधुनिक Swift प्रोजेक्ट्स में निर्भरता प्रबंधन का मानक उपकरण बनाता है। इस लेख में हम Package.swift की संरचना, SPM कमांड, स्वयं के पैकेज बनाने और वैकल्पिक प्रबंधकों से माइग्रेशन पर चर्चा करेंगे।
मुख्य बिंदु
SPM (Swift Package Manager) Swift भाषा के लिए आधिकारिक पैकेज प्रबंधक है, जो swiftc कंपाइलर और Xcode विकास पर्यावरण में निर्मित है। यह डेवलपर्स को तृतीय-पक्ष लाइब्रेरीज़ जोड़ने, उनके संस्करणों का प्रबंधन करने और अपने स्वयं के पैकेज प्रकाशित करने की अनुमति देता है। SPM पहली बार Swift 3.0 (सितंबर 2016) में एक कमांड-लाइन उपकरण के रूप में दिखाई दिया, और Xcode 11 (2019) से इसे ग्राफ़िकल इंटरफ़ेस के साथ पूर्ण एकीकरण प्राप्त हुआ — अब निर्भरताएँ File → Add Packages मेनू के माध्यम से जोड़ी जाती हैं।
SPM स्वचालित रूप से Git रिपॉजिटरी से निर्भरताओं का स्रोत कोड डाउनलोड करता है, उन्हें मुख्य प्रोजेक्ट के साथ समानांतर रूप से बनाता है और परिणामों को कैश करता है ताकि बाद के बिल्ड तेज़ी से निष्पादित हों। CocoaPods के विपरीत, SPM एक अलग वर्कस्पेस (xcworkspace) उत्पन्न नहीं करता — निर्भरताएँ मुख्य Xcode प्रोजेक्ट का हिस्सा बन जाती हैं। Swift.org Developer Survey (2024) के अनुसार, 67% iOS डेवलपर SPM का उपयोग करते हैं, जो इसे Swift इकोसिस्टम में सबसे लोकप्रिय निर्भरता प्रबंधन उपकरण बनाता है।
SPM तीन प्लेटफ़ॉर्म का समर्थन करता है: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux) और सर्वर-साइड Swift (Vapor, Kitura)। Linux पर, SPM Xcode के बिना पूरी तरह से कमांड लाइन के माध्यम से काम करता है।
SPM तीन मुख्य अवधारणाओं के आसपास बनाया गया है: पैकेज (packages), उत्पाद (products) और लक्ष्य (targets)। पैकेज Package.swift मेनिफ़ेस्ट के साथ एक Git रिपॉजिटरी है। उत्पाद बिल्ड का परिणाम है (एक लाइब्रेरी या एक निष्पादन योग्य फ़ाइल)। लक्ष्य पैकेज के अंदर एक मॉड्यूल है जो एक बिल्ड इकाई में संकलित होता है।
जब कोई डेवलपर Package.swift में कोई निर्भरता जोड़ता है, तो SPM निम्नलिखित चरण निष्पादित करता है:
~Library/Caches/org.swift.swiftpm/ में सहेजता है।Package.resolved फ़ाइल सभी निर्भरताओं के सटीक संस्करणों को लॉक करती है ताकि विकास टीम लाइब्रेरीज़ के समान सेट के साथ काम करे। इस फ़ाइल को संस्करण नियंत्रण (git) में जोड़ा जाना चाहिए।
SPM का विकल्पों पर एक मुख्य लाभ केंद्रीकृत रजिस्ट्री का अभाव है। पैकेज किसी भी सार्वजनिक Git रिपॉजिटरी में रह सकते हैं: GitHub, GitLab, Bitbucket, साथ ही कंपनी के निजी Git सर्वर पर भी। Swift 5.2 से, SPM बाइनरी निर्भरताओं (बाइनरी टार्गेट) का समर्थन करता है — स्रोत कोड प्रदान किए बिना XCFramework के रूप में वितरित बंद-स्रोत लाइब्रेरीज़।
Package.swift एक Swift फ़ाइल है जो पैकेज संरचना और उसकी निर्भरताओं का वर्णन करती है। फ़ाइल स्वयं Swift में लिखी जाती है (JSON या YAML नहीं), जो मेनिफ़ेस्ट के अंदर सशर्त तर्क, गणना की गई स्थिरांक और फ़ंक्शन का उपयोग करने की अनुमति देती है।
Package.swift की मूल संरचना:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyLibrary",
platforms: [
.iOS(.v16),
.macOS(.v13)
],
products: [
.library(
name: "MyLibrary",
targets: ["MyLibrary"]
),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"),
.package(url: "https://github.com/onevcat/Kingfisher.git",
from: "7.12.0"),
],
targets: [
.target(
name: "MyLibrary",
dependencies: [
"Alamofire",
"Kingfisher"
]
),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"]
),
]
)
आइए मुख्य तत्वों को समझें:
// swift-tools-version: 5.9 — SPM संस्करण निर्दिष्ट करने वाला निर्देश; इस पर मेनिफ़ेस्ट का उपलब्ध सिंटैक्स निर्भर करता है।name — पैकेज का नाम, Xcode में प्रदर्शित होता है और निर्भरता लिंक में उपयोग होता है।platforms — न्यूनतम प्लेटफ़ॉर्म संस्करण; SPM पुराने OS संस्करण पर पैकेज बनाने की अनुमति नहीं देगा।products — पैकेज क्या "निर्यात" करता है: एक लाइब्रेरी (.library) या एक निष्पादन योग्य (.executable)।dependencies — URL और संस्करण के साथ बाहरी पैकेजों की सूची; from:, exact:, branch:, revision: का समर्थन करता है।targets — बिल्ड लक्ष्य; प्रत्येक लक्ष्य में संबंधित निर्देशिका से निर्भरताओं, संसाधनों और swift फ़ाइलों की सूची होती है (Sources/TargetName/)।सटीक संस्करण, शाखा और कमिट निर्दिष्ट करने का उदाहरण:
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git",
exact: "1.17.3"),
.package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",
branch: "main"),
.package(url: "https://github.com/apple/swift-log.git",
revision: "e5c6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4"),
]
Swift 5.9 से, Package.swift में static framework और linkerSettings के लिए समर्थन जोड़ा गया है, जो स्थिर और गतिशील लाइब्रेरीज़ के लिए अधिक सटीक लिंकर कॉन्फ़िगरेशन की अनुमति देता है।
Swift Package Manager टर्मिनल के माध्यम से काम करने के लिए कमांड का एक सेट प्रदान करता है। कमांड पैकेज की मूल निर्देशिका (जहाँ Package.swift स्थित है) से चलाए जाते हैं।
# लाइब्रेरी के साथ नया पैकेज बनाएं
swift package init --type library
# निष्पादन योग्य पैकेज बनाएं (कंसोल एप्लिकेशन)
swift package init --type executable
# प्रोजेक्ट बनाएं
swift build
# रिलीज़ कॉन्फ़िगरेशन में बनाएं
swift build -c release
# परीक्षण चलाएं
swift test
# विशिष्ट परीक्षण चलाएं
swift test --filter "MyLibraryTests/testExample"
# निर्भरताएँ डाउनलोड और समाधान करें
swift package resolve
# निर्भरताओं को नवीनतम उपलब्ध संस्करणों में अपडेट करें
swift package update
# निर्भरता ग्राफ़ दिखाएं
swift package show-dependencies
# बिल्ड कैश साफ़ करें
swift package clean
# Xcode प्रोजेक्ट जनरेट करें (Xcode 11 से पहले)
swift package generate-xcodeproj
Xcode के अंदर काम करते समय, इनमें से अधिकांश कमांड स्वचालित रूप से निष्पादित होते हैं: प्रोजेक्ट खोलने पर निर्भरताएँ हल हो जाती हैं, ⌘B से बिल्ड शुरू होता है, ⌘U से परीक्षण। हालांकि, CI/CD पाइपलाइनों (GitHub Actions, GitLab CI, Jenkins) के लिए टर्मिनल कमांड का ज्ञान आवश्यक है जहाँ Xcode उपलब्ध नहीं है।
swift package resolve कमांड Package.resolved फ़ाइल बनाता या अपडेट करता है। यह फ़ाइल ट्रांज़िटिव सहित सभी निर्भरताओं के सटीक संस्करणों को लॉक करती है, और इसे git में जोड़ा जाना चाहिए। प्रत्येक नई सुविधा शाखा से पहले अद्यतित लाइब्रेरी संस्करणों के साथ काम करने के लिए swift package update चलाने की अनुशंसा की जाती है।
अपना खुद का SPM पैकेज बनाना बहु-मॉड्यूल प्रोजेक्ट्स में व्यावसायिक तर्क को एनकैप्सुलेट करने और ओपन-सोर्स लाइब्रेरीज़ प्रकाशित करने के लिए उपयोगी है। आइए चरण-दर-चरण प्रक्रिया देखें।
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library
swift package init कमांड निम्नलिखित संरचना बनाता है:
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│ └── MyNetworkKit/
│ └── MyNetworkKit.swift
└── Tests/
└── MyNetworkKitTests/
└── MyNetworkKitTests.swift
SPM स्वचालित रूप से Sources/ और Tests/ निर्देशिकाओं को स्कैन करता है: Sources के अंदर प्रत्येक उपनिर्देशिका एक लक्ष्य (टार्गेट) के अनुरूप होती है।
चलिए निर्भरताएँ जोड़ें और लक्ष्य प्लेटफ़ॉर्म कॉन्फ़िगर करें:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyNetworkKit",
platforms: [
.iOS(.v15),
.macOS(.v12)
],
products: [
.library(
name: "MyNetworkKit",
targets: ["MyNetworkKit"]
),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"),
],
targets: [
.target(
name: "MyNetworkKit",
dependencies: ["Alamofire"]
),
.testTarget(
name: "MyNetworkKitTests",
dependencies: ["MyNetworkKit"]
),
]
)
// Sources/MyNetworkKit/MyNetworkKit.swift
import Foundation
import Alamofire
public struct NetworkClient {
private let session: Session
public init() {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
self.session = Session(configuration: configuration)
}
public func fetchData(from url: String) async throws -> Data {
let response = try await session.request(url).serializingData().value
return response
}
}
पैकेज को Git रिपॉजिटरी में पुश करें और SemVer टैग बनाएं:
git init
git add .
git commit -m "Initial commit: MyNetworkKit"
git remote add origin https://github.com/username/MyNetworkKit.git
git push -u origin main
git tag 1.0.0
git push --tags
इसके बाद, कोई भी डेवलपर .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0") का उपयोग करके आपका पैकेज जोड़ सकता है।
Alamofire Swift के लिए सबसे लोकप्रिय HTTP क्लाइंट है। चलिए इसे SPM के माध्यम से जोड़ें और GET अनुरोध करें।
import Alamofire
func fetchUsers() {
AF.request("https://jsonplaceholder.typicode.com/users")
.validate()
.responseDecodable(of: [User].self) { response in
switch response.result {
case .success(let users):
print("(users.count) उपयोगकर्ता प्राप्त हुए")
case .failure(let error):
print("त्रुटि: (error.localizedDescription)")
}
}
}
Swinject लाइब्रेरी Swift के लिए DI कंटेनर प्रदान करती है। इसे .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0") के माध्यम से जोड़ा जाता है।
import Swinject
let container = Container()
container.register(NetworkServiceProtocol.self) { _ in NetworkService() }
container.register(DataRepositoryProtocol.self) { r in
DataRepository(networkService: r.resolve(NetworkServiceProtocol.self)!)
}
let repository = container.resolve(DataRepositoryProtocol.self)
repository?.loadData()
Apple का swift-log पैकेज एक एकीकृत लॉगिंग API प्रदान करता है जो कई बैकएंड (OSLog, कंसोल, फ़ाइलें) का समर्थन करता है।
import Logging
var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug
logger.info("नेटवर्क अनुरोध शुरू हुआ", metadata: [
"url": "(requestURL)",
"method": "GET"
])
logger.warning("प्रतिक्रिया समय 2 सेकंड से अधिक हो गया")
logger.error("कनेक्शन त्रुटि: कोई इंटरनेट नहीं")
ये तीन उदाहरण SPM के विशिष्ट उपयोग परिदृश्यों को कवर करते हैं: HTTP क्लाइंट, DI कंटेनर और सिस्टम बुनियादी ढाँचा। लाइब्रेरी का चयन आकस्मिक नहीं है — Alamofire, Swinject और swift-log GitHub पर सबसे अधिक स्टार वाले शीर्ष 20 Swift पैकेजों में शामिल हैं।
यदि आपका प्रोजेक्ट CocoaPods या Carthage का उपयोग करता है, तो SPM में माइग्रेशन कुछ चरणों में किया जाता है। प्रक्रिया सुरक्षित है: SPM निर्भरताएँ उसी प्रोजेक्ट में CocoaPods और Carthage के साथ सह-अस्तित्व में रह सकती हैं, जिससे क्रमिक माइग्रेशन संभव होता है।
.xcworkspace हटाएँ, .xcodeproj खोलें और Clean Build Folder करें।rm -rf Carthage/ चलाएँ।2025 तक, SPM अधिकांश लोकप्रिय Swift लाइब्रेरीज़ का समर्थन करता है। अपवाद कुछ ObjC फ्रेमवर्क हैं जिनमें मॉड्यूल मैप नहीं है। यदि कोई लाइब्रेरी अभी तक SPM का समर्थन नहीं करती है — तो उसके README में Installation अनुभाग देखें; अधिकांश लेखकों ने नवीनतम संस्करणों में SPM समर्थन पहले ही जोड़ दिया है।
अक्सर पूछे जाने वाले प्रश्न
SPM Swift कंपाइलर और Xcode में निर्मित है, इसे gem या Homebrew के माध्यम से स्थापित करने की आवश्यकता नहीं है। CocoaPods एक केंद्रीकृत Specs रजिस्ट्री का उपयोग करता है और एक अलग वर्कस्पेस उत्पन्न करता है। Carthage प्रोजेक्ट एकीकरण के बिना फ्रेमवर्क के माध्यम से काम करता है। SPM एकमात्र प्रबंधक है जो कंपाइलर स्तर पर एकीकृत है: निर्भरताएँ मुख्य कोड के साथ समानांतर रूप से हल, कैश और निर्मित की जाती हैं।
हाँ, SPM मिश्रित Swift + Objective-C प्रोजेक्ट्स का समर्थन करता है। SPM पैकेज के अंदर ObjC फ़ाइलें स्वचालित रूप से Umbrella Header में शामिल हो जाती हैं बशर्ते सही modulemap मौजूद हो। हालांकि, SPM उन स्थिर ObjC लाइब्रेरीज़ का समर्थन नहीं करता जिनमें मॉड्यूल मैप नहीं है। ObjC लाइब्रेरीज़ को SPM के माध्यम से केवल तभी जोड़ने की अनुशंसा की जाती है यदि वे modulemap प्रदान करती हैं या शुद्ध C में लिखी गई हैं।
SPM सिमैंटिक वर्ज़निंग (SemVer) का उपयोग करता है। यदि पैकेज A को Alamofire 5.8+ चाहिए और पैकेज B को Alamofire 5.9+ चाहिए, तो SPM दोनों को संतुष्ट करने वाला संस्करण 5.9.x चुनेगा। यदि विरोध हल करने योग्य नहीं है (एक पैकेज को 5.x चाहिए, दूसरे को 6.x), तो SPM त्रुटि की रिपोर्ट करेगा। उस स्थिति में आपको एक पैकेज को अपडेट करना होगा या निर्भरता को दोनों आवश्यकताओं के साथ संगत संस्करण में बदलना होगा।
macOS पर: ~Library/Caches/org.swift.swiftpm/ और ~/Library/Developer/Xcode/DerivedData/। Linux पर: ~cache/swiftpm/। बिल्ड के दौरान, SPM स्रोत कोड और संकलित ऑब्जेक्ट फ़ाइलों को कैश करता है। कैश को पूरी तरह से साफ़ करने के लिए, swift package reset चलाएँ — यह कमांड वर्तमान प्रोजेक्ट के लिए निर्भरता कैश और DerivedData हटा देता है।
हाँ, Swift 5.2 से SPM बाइनरी टार्गेट का समर्थन करता है। एक बंद-स्रोत लाइब्रेरी XCFramework के रूप में वितरित की जाती है, और .xcframework का पथ Package.swift में निर्दिष्ट किया जाता है। स्रोत कोड उजागर नहीं होता है। बाइनरी टार्गेट .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework") के माध्यम से निर्दिष्ट किया जाता है। यह लाइसेंस समझौतों का उल्लंघन किए बिना वाणिज्यिक SDK को जोड़ने की अनुमति देता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।