{ "id": "175546", "key": "TIMOB-28141", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": null, "resolutiondate": null, "created": "2020-09-16T14:14:38.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [], "versions": [], "issuelinks": [], "assignee": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2020-12-20T10:01:10.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" }, { "id": "15102", "name": "Mac", "description": "Mac authoring support" } ], "description": "In the modern iOS/macOS ecosystem, the Apple-owned \"Swift Package Manager\" is the new way of managing external dependencies. While other solutions like Cocoapods and Carthage still exist, the future is definitely the Swift Package Manager.\r\n\r\nIn general, you just ned to paste the Github link of the library into Xcode, select the version (or version range) and Xcode will find the correct version of the library.\r\n\r\nThis is already possible in modules today (I wondered as well), but the problem is that the SPM settings belong into the generated app, not the module Xcode project.\r\n\r\nTechnically, what it needs to support this, is *relatively* simple:\r\n# Verify the module / app extension compilation. This probably does not need *any* changes, because mainly {{xcodebuild}} is used here and that works\r\n# Copy the {{Package.resolved}} file of the module into the module zip. It looks like this:\r\n{code}\r\n{\r\n \"object\": {\r\n \"pins\": [\r\n {\r\n \"package\": \"Kingfisher\",\r\n \"repositoryURL\": \"https://github.com/onevcat/Kingfisher\",\r\n \"state\": {\r\n \"branch\": null,\r\n \"revision\": \"175eeb4618b0a6ef4d69a7409b6a74ddd235a093\",\r\n \"version\": \"5.15.0\"\r\n }\r\n }\r\n ]\r\n },\r\n \"version\": 1\r\n}\r\n{code}\r\n# Reference the {{Package.resolved}} during build and re-generate the pbxproj references for SPM:\r\n{code}\r\n/* Begin XCRemoteSwiftPackageReference section */\r\n\t\t3A0F5BDD251250E300E8829E /* XCRemoteSwiftPackageReference \"Kingfisher\" */ = {\r\n\t\t\tisa = XCRemoteSwiftPackageReference;\r\n\t\t\trepositoryURL = \"https://github.com/onevcat/Kingfisher\";\r\n\t\t\trequirement = {\r\n\t\t\t\tkind = exactVersion;\r\n\t\t\t\tversion = 5.15.0;\r\n\t\t\t};\r\n\t\t};\r\n/* End XCRemoteSwiftPackageReference section */\r\n\r\n/* Begin XCSwiftPackageProductDependency section */\r\n\t\t3A0F5BDE251250E300E8829E /* KingfisherSwiftUI */ = {\r\n\t\t\tisa = XCSwiftPackageProductDependency;\r\n\t\t\tpackage = 3A0F5BDD251250E300E8829E /* XCRemoteSwiftPackageReference \"Kingfisher\" */;\r\n\t\t\tproductName = KingfisherSwiftUI;\r\n\t\t};\r\n\t\t3A0F5BE0251250E300E8829E /* Kingfisher */ = {\r\n\t\t\tisa = XCSwiftPackageProductDependency;\r\n\t\t\tpackage = 3A0F5BDD251250E300E8829E /* XCRemoteSwiftPackageReference \"Kingfisher\" */;\r\n\t\t\tproductName = Kingfisher;\r\n\t\t};\r\n/* End XCSwiftPackageProductDependency section */\r\n{code}\r\nAll required data of that can be received from the {{Package.resolved}} file of each module :-)\r\n# Finally: Add the framework references to the pbxproj like before, e.g.\r\n{code}\r\n\t\t3A0F5BDF251250E300E8829E /* KingfisherSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3A0F5BDE251250E300E8829E /* KingfisherSwiftUI */; };\r\n\t\t3A0F5BE1251250E300E8829E /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 3A0F5BE0251250E300E8829E /* Kingfisher */; };\r\n{code}\r\n\r\nI can assist with sample projects and further information if requested!\r\n\r\nP.S.: Supporting this, modules will also shrink in size by > 95% and make the Appc Github CI happy :) ", "attachment": [], "flagged": false, "summary": "iOS/macOS: Support Swift Package Manager (SPM) in modules", "creator": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "environment": null, "comment": { "comments": [ { "id": "457946", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "An early PoC of modules using Swift Package Manager (SPM) dependencies for the Facebook SDK: https://github.com/appcelerator-modules/ti.facebook/pull/192\r\n\r\nThe open issue is described in the issue:\r\n{quote}\r\nThis was the easy part. The tricky part will be how to pull these dependencies into the generated project.\r\n\r\nThe solution could be to package the whole module project and do not attempt to generate a module library at all. That's basically was SPM does as well. Xcode will handle the framework caching in the DerivedData directory and Titanium \"just\" embeds each module project into the main project.\r\n\r\nAn alternative could be that Titanium maintains an own config file for it's iOS dependencies, but that would (again) introduce an additional overhead to be handled manually.\r\n{quote}\r\n\r\nOpen for discussion!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-12-20T10:01:10.000+0000", "updated": "2020-12-20T10:01:10.000+0000" } ], "maxResults": 2, "total": 2, "startAt": 0 } } }