SPM: คืออะไร, Swift Package Manager และ Package.swift

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-02-13 เวลาอ่าน: 11 นาที

SPM (Swift Package Manager) เป็นตัวจัดการแพ็คเกจในตัวของระบบนิเวศ Swift ที่พัฒนาโดย Apple เพื่อทำให้การเชื่อมต่อ สร้าง และอัปเดตไลบรารีของบุคคลที่สามเป็นอัตโนมัติ SPM เป็นส่วนหนึ่งของคอมไพเลอร์ Swift ตั้งแต่เวอร์ชัน 3.0 (ปี 2016) และไม่ต้องการการติดตั้งแยกต่างหาก แตกต่างจาก CocoaPods และ Carthage ตรงที่ SPM ผสานรวมโดยตรงกับคอมไพเลอร์และ Xcode ทำให้เป็นเครื่องมือมาตรฐานสำหรับการจัดการการพึ่งพาในโปรเจกต์ Swift สมัยใหม่ ในบทความนี้เราจะอธิบายโครงสร้างของ Package.swift คำสั่ง SPM การสร้างแพ็คเกจของตัวเอง และการย้ายจากตัวจัดการอื่น

ประเด็นสำคัญ

  • SPM (Swift Package Manager) เป็นตัวจัดการแพ็คเกจที่สร้างอยู่ในคอมไพเลอร์ Swift ไม่ต้องการการติดตั้งแยกต่างหาก ทำงานบน iOS, macOS, Linux และแพลตฟอร์มเซิร์ฟเวอร์
  • Package.swift เป็นไฟล์แมนิเฟสต์ที่อธิบายชื่อแพ็คเกจ แพลตฟอร์ม การพึ่งพา และโมดูลเป้าหมาย (targets) ในรูปแบบประกาศ
  • SPM แก้ไขการพึ่งพาโดยใช้กำหนดเวอร์ชันเชิงความหมาย (SemVer) แคชซอร์สโค้ด และสร้างแพ็คเกจแบบขนานเพื่อความรวดเร็ว
  • คำสั่ง: swift package init (สร้างแพ็คเกจ), swift package update (อัปเดตการพึ่งพา), swift build (สร้าง), swift test (รันทดสอบ)
  • การย้ายจาก CocoaPods/Carthage ไป SPM ทำผ่าน Xcode: File → Add Package Dependency จากนั้นลบ podfile และ Cartfile

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) นักพัฒนา iOS 67% ใช้ SPM ทำให้เป็นเครื่องมือจัดการการพึ่งพาที่ได้รับความนิยมมากที่สุดในระบบนิเวศ Swift

SPM รองรับสามแพลตฟอร์ม: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux) และ Swift ฝั่งเซิร์ฟเวอร์ (Vapor, Kitura) บน Linux SPM ทำงานผ่านบรรทัดคำสั่งโดยไม่มี Xcode

Swift Package Manager ทำงานอย่างไร

SPM สร้างขึ้นจากแนวคิดหลักสามประการ: แพ็คเกจ (packages), ผลิตภัณฑ์ (products) และ เป้าหมาย (targets) แพ็คเกจคือที่เก็บ Git ที่มีแมนิเฟสต์ Package.swift ผลิตภัณฑ์คือผลลัพธ์ของการสร้าง (ไลบรารีหรือไฟล์ปฏิบัติการ) เป้าหมายคือโมดูลภายในแพ็คเกจที่ถูกคอมไพล์เป็นหน่วยสร้าง

เมื่อนักพัฒนาเพิ่มการพึ่งพาใน Package.swift SPM จะดำเนินการตามขั้นตอนต่อไปนี้:

  1. โคลน — SPM ดาวน์โหลดที่เก็บ Git ของการพึ่งพาจาก URL ที่ระบุ
  2. แก้ไขเวอร์ชัน — วิเคราะห์แท็ก SemVer (เช่น 2.1.3) และเลือกเวอร์ชันที่เหมาะสมภายในช่วงที่ระบุ
  3. แก้ไขแบบทรานซิทีฟ — ตรวจสอบการพึ่งพาของการพึ่งพาและสร้างกราฟเวอร์ชันที่ไม่ขัดแย้งกัน
  4. แคช — บันทึกซอร์สโค้ดที่ดาวน์โหลดใน ~Library/Caches/org.swift.swiftpm/
  5. คอมไพล์ — สร้างเป้าหมายทั้งหมดของแพ็คเกจด้วยแฟลกของโปรเจกต์หลัก

ไฟล์ Package.resolved ล็อกเวอร์ชันที่แน่นอนของการพึ่งพาทั้งหมด เพื่อให้ทีมพัฒนาทำงานกับชุดไลบรารีที่เหมือนกัน ไฟล์นี้ควรถูกเพิ่มในระบบควบคุมเวอร์ชัน (git)

ข้อได้เปรียบหลักของ SPM เหนือทางเลือกอื่นคือ การไม่มีรีจิสทรีแบบรวมศูนย์ แพ็คเกจสามารถอยู่ในที่เก็บ Git สาธารณะใดก็ได้: GitHub, GitLab, Bitbucket รวมถึงบนเซิร์ฟเวอร์ Git ส่วนตัวของบริษัท ตั้งแต่ Swift 5.2 SPM รองรับ การพึ่งพาแบบไบนารี (binary targets) — ไลบรารีแบบปิดที่แจกจ่ายเป็น XCFramework โดยไม่ให้ซอร์สโค้ด

Package.swift — แมนิเฟสต์โปรเจกต์

Package.swift เป็นไฟล์ Swift ที่อธิบายโครงสร้างของแพ็คเกจและการพึ่งพาของมัน ไฟล์เขียนด้วย Swift เอง (ไม่ใช่ JSON หรือ YAML) ซึ่งช่วยให้可以使用ตรรกะแบบมีเงื่อนไข ค่าคงที่ที่คำนวณได้ และฟังก์ชันภายในแมนิเฟสต์

โครงสร้างพื้นฐานของ Package.swift:

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/)

ตัวอย่างการระบุเวอร์ชันที่แน่นอน สาขา และ commit:

swift
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 ซึ่งช่วยให้กำหนดค่าลิงเกอร์ได้แม่นยำยิ่งขึ้นสำหรับไลบรารีแบบสแตติกและไดนามิก

คำสั่ง SPM พื้นฐาน

Swift Package Manager มีชุดคำสั่งสำหรับทำงานผ่านเทอร์มินัล คำสั่งจะรันจากไดเรกทอรีรากของแพ็คเกจ (ที่ซึ่ง Package.swift อยู่)

bash
# สร้างแพ็คเกจใหม่พร้อมไลบรารี
swift package init --type library

# สร้างแพ็คเกจที่ปฏิบัติการได้ (แอปพลิเคชันคอนโซล)
swift package init --type executable

# สร้างโปรเจกต์
swift build

# สร้างในคอนฟิกูเรชัน release
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 ของคุณเองมีประโยชน์สำหรับการห่อหุ้มตรรกะทางธุรกิจในโปรเจกต์แบบหลายโมดูลและการเผยแพร่ไลบรารีโอเพนซอร์ส มาดูกระบวนการทีละขั้นตอน

ขั้นตอนที่ 1: การเริ่มต้น

bash
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library

ขั้นตอนที่ 2: โครงสร้างไดเรกทอรี

คำสั่ง swift package init สร้างโครงสร้างดังนี้:

text
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│   └── MyNetworkKit/
│       └── MyNetworkKit.swift
└── Tests/
    └── MyNetworkKitTests/
        └── MyNetworkKitTests.swift

SPM จะสแกนไดเรกทอรี Sources/ และ Tests/ โดยอัตโนมัติ: แต่ละไดเรกทอรีย่อยภายใน Sources สอดคล้องกับเป้าหมาย (target) หนึ่งเป้าหมาย

ขั้นตอนที่ 3: แก้ไข Package.swift

มาเพิ่มการพึ่งพาและกำหนดค่าแพลตฟอร์มเป้าหมาย:

swift
// 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"]
        ),
    ]
)

ขั้นตอนที่ 4: การเขียนโค้ด

swift
// 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
    }
}

ขั้นตอนที่ 5: การเผยแพร่

พุชแพ็คเกจไปยังที่เก็บ Git และสร้างแท็ก SemVer:

bash
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")

ตัวอย่างการใช้งาน SPM

ตัวอย่างที่ 1: การเพิ่ม Alamofire สำหรับคำขอเครือข่าย

Alamofire เป็น HTTP client ยอดนิยมที่สุดสำหรับ Swift มาเพิ่มผ่าน SPM และทำคำขอ GET กัน

swift
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)")
            }
        }
}

ตัวอย่างที่ 2: Swinject — การฉีดพึ่งพา

ไลบรารี Swinject ให้คอนเทนเนอร์ DI สำหรับ Swift เพิ่มผ่าน .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0")

swift
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()

ตัวอย่างที่ 3: Swift-log สำหรับการบันทึกแบบมีโครงสร้าง

แพ็คเกจ swift-log จาก Apple ให้ API การบันทึกแบบรวมที่รองรับแบ็กเอนด์หลายตัว (OSLog, คอนโซล, ไฟล์)

swift
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 clients, DI containers และโครงสร้างพื้นฐานระบบ การเลือกไลบรารีไม่ใช่เรื่องบังเอิญ — Alamofire, Swinject และ swift-log อยู่ใน 20 อันดับแรกของแพ็คเกจ Swift ที่มีดาวมากที่สุดบน GitHub

การย้ายจาก CocoaPods และ Carthage

หากโปรเจกต์ของคุณใช้ CocoaPods หรือ Carthage การย้ายไป SPM ทำได้ไม่กี่ขั้นตอน กระบวนการนี้ปลอดภัย: การพึ่งพาของ SPM สามารถอยู่ร่วมกับ CocoaPods และ Carthage ในโปรเจกต์เดียวกันได้ ทำให้ย้ายได้ทีละน้อย

CocoaPods → SPM

  1. ใน Xcode: File → Add Package Dependency ป้อน URL ของแพ็คเกจ
  2. เลือกเวอร์ชันและเพิ่มแพ็คเกจไปยังเป้าหมายที่ต้องการ
  3. หลังจากเพิ่มการพึ่งพาทั้งหมดผ่าน SPM แล้ว ลบบรรทัดจาก Podfile
  4. ลบ .xcworkspace เปิด .xcodeproj และดำเนินการ Clean Build Folder

Carthage → SPM

  1. เพิ่มแพ็คเกจผ่าน Xcode File → Add Package Dependency
  2. ลบการพึ่งพาจาก Cartfile
  3. ลบสคริปต์สร้าง Carthage จาก Build Phases
  4. ล้างแคช: rm -rf Carthage/ ในเทอร์มินัล

ณ ปี 2025 SPM รองรับไลบรารี Swift ยอดนิยมส่วนใหญ่ ข้อยกเว้นคือบางเฟรมเวิร์ก ObjC ที่ไม่มีแผนที่โมดูล หากไลบรารียังไม่รองรับ SPM — ตรวจสอบส่วน Installation ใน README ของมัน; ผู้เขียนส่วนใหญ่ได้เพิ่มการรองรับ SPM ในเวอร์ชันล่าสุดแล้ว

คำถามที่พบบ่อย

SPM แตกต่างจาก CocoaPods และ Carthage อย่างไร?

SPM สร้างอยู่ในคอมไพเลอร์ Swift และ Xcode ไม่ต้องติดตั้งผ่าน gem หรือ Homebrew CocoaPods ใช้รีจิสทรี Specs แบบรวมศูนย์และสร้างเวิร์กสเปซแยกต่างหาก Carthage ทำงานผ่านเฟรมเวิร์กโดยไม่ผสานรวมกับโปรเจกต์ SPM เป็นตัวจัดการเดียวที่ผสานรวมในระดับคอมไพเลอร์: การพึ่งพาจะถูกแก้ไข แคช และสร้างแบบขนานกับโค้ดหลัก

สามารถใช้ SPM สำหรับโปรเจกต์ Objective-C ได้หรือไม่?

ได้ SPM รองรับโปรเจกต์แบบผสม Swift + Objective-C ไฟล์ ObjC ภายในแพ็คเกจ SPM จะถูกรวมใน Umbrella Header โดยอัตโนมัติหากมี modulemap ที่ถูกต้อง อย่างไรก็ตาม SPM ไม่รองรับไลบรารี ObjC แบบสแตติกที่ไม่มีแผนที่โมดูล แนะนำให้เชื่อมต่อไลบรารี ObjC ผ่าน SPM เฉพาะเมื่อมี modulemap หรือเขียนด้วย C บริสุทธิ์

SPM แก้ไขข้อขัดแย้งของเวอร์ชันอย่างไร?

SPM ใช้กำหนดเวอร์ชันเชิงความหมาย (SemVer) หากแพ็คเกจ A ต้องการ Alamofire 5.8+ และแพ็คเกจ B ต้องการ Alamofire 5.9+ SPM จะเลือกเวอร์ชัน 5.9.x ที่ตอบสนองทั้งคู่ หากข้อขัดแย้งไม่สามารถแก้ไขได้ (แพ็คเกจหนึ่งต้องการ 5.x อีกแพ็คเกจต้องการ 6.x) SPM จะรายงานข้อผิดพลาด ในกรณีนี้คุณต้องอัปเดตแพ็คเกจใดแพ็คเกจหนึ่งหรือเปลี่ยนการพึ่งพาเป็นเวอร์ชันที่เข้ากันได้กับทั้งสองข้อกำหนด

แพ็คเกจ SPM ที่ดาวน์โหลดแล้วถูกเก็บไว้ที่ไหน?

บน macOS: ~Library/Caches/org.swift.swiftpm/ และ ~/Library/Developer/Xcode/DerivedData/ บน Linux: ~cache/swiftpm/ ระหว่างการสร้าง SPM จะแคชซอร์สโค้ดและไฟล์ออบเจ็กต์ที่คอมไพล์แล้ว หากต้องการล้างแคชทั้งหมด ให้รัน swift package reset — คำสั่งนี้จะลบแคชการพึ่งพาและ DerivedData สำหรับโปรเจกต์ปัจจุบัน

SPM รองรับไลบรารีแบบปิด (กรรมสิทธิ์) หรือไม่?

ได้ ตั้งแต่ Swift 5.2 SPM รองรับเป้าหมายแบบไบนารี (binary targets) ไลบรารีแบบปิดถูกแจกจ่ายเป็น XCFramework และระบุพาธไปยัง .xcframework ใน Package.swift ซอร์สโค้ดจะไม่ถูกเปิดเผย เป้าหมายแบบไบนารีระบุผ่าน .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework") ซึ่งช่วยให้เชื่อมต่อ SDK เชิงพาณิชย์โดยไม่ละเมิดข้อตกลงใบอนุญาต

สรุป

  • SPM (Swift Package Manager) เป็นตัวจัดการแพ็คเกจที่สร้างอยู่ใน Swift ไม่ต้องติดตั้งแยกต่างหากและผสานรวมกับ Xcode และคอมไพเลอร์
  • Package.swift เป็นแมนิเฟสต์แบบประกาศที่เขียนด้วย Swift อธิบายชื่อแพ็คเกจ แพลตฟอร์ม การพึ่งพา ผลิตภัณฑ์ และเป้าหมายการสร้าง
  • SPM ใช้ที่เก็บ Git เป็นแหล่งแพ็คเกจและแก้ไขเวอร์ชันผ่าน SemVer แคชซอร์สโค้ดเพื่อการสร้างครั้งต่อไปที่เร็วขึ้น
  • คำสั่งหลัก: swift package init (สร้างแพ็คเกจ), swift build (สร้าง), swift test (ทดสอบ), swift package update (อัปเดตการพึ่งพา)
  • แพ็คเกจที่กำหนดเองสร้างผ่าน swift package init เผยแพร่บน Git และพร้อมให้โปรเจกต์อื่นใช้ผ่าน URL พร้อมแท็ก SemVer
  • การย้ายจาก CocoaPods/Carthage ไป SPM ปลอดภัย: การพึ่งพาสามารถอยู่ร่วมกันได้ การย้ายทำผ่าน File → Add Package Dependency ใน Xcode
  • SPM เป็นเครื่องมือจัดการการพึ่งพามาตรฐานในระบบนิเวศ Swift ใช้โดยนักพัฒนา iOS 67% (Swift.org Developer Survey, 2024)

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม