{ "id": "138381", "key": "TIMOB-17888", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "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": { "id": "3", "description": "The problem is a duplicate of an existing issue.", "name": "Duplicate" }, "resolutiondate": "2018-04-05T19:23:53.000+0000", "created": "2014-10-22T15:09:06.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "ios8", "modules", "swift" ], "versions": [], "issuelinks": [ { "id": "42319", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "138397", "key": "TIMOB-17887", "fields": { "summary": "iOS: Add Swift modules support", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "6", "description": "gh.issue.epic.desc", "name": "Epic", "subtask": false } } } } ], "assignee": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "updated": "2018-08-06T17:41:11.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "Modules that have frameworks built using Swift do not work. Modules compile, but when you try to build an app using the module, you get errors:\r\n\r\n{code}\r\nld: embedded dylibs/frameworks are only supported on iOS 8.0 and later (@rpath/ChasePaymentech.framework/ChasePaymentech) for architecture i386\r\n{code}\r\n\r\nAs you can see from the error, we attempted to implement the Chase Paymentech SDK. Chase puts the Paymentech SDK download behind a login wall... We can't provide it, but you can sign up (free) and download it.\r\n\r\nSo, to reproduce this error (and possibly fix it), my steps:\r\n\r\nh4. Create the module\r\n# ti create -n ti.test -p ios --id ti.test -t module -url \"http://test.com\" -d .\r\n# Open up the project in Xocde. Confirm it builds.\r\n# Download the library from https://secure.paymentech.com/developercenter/mobilesdk/ios/?WT.mc_id=adc001_sdk\r\n# Place the .framework file in /iphone/platform\r\n# Drag the file into the source explorer in Xcode. No need to copy it (as it's already in the project). Or you can follow the linking instructions in the paymenttech docs\r\n# Edit the module.xcconfig file to reference the framework:\r\n\r\n{code}\r\n//\r\n// How to add a Framework (example)\r\n//\r\n\r\nOTHER_LDFLAGS=$(inherited) -framework ChasePaymentech\r\n{code}\r\n\r\nThe module builds without error for me (both from inside Xcode and from the command line).\r\n\r\nh4. Create the application\r\n# Drop the built module into the global module cache (Unzipped). For me this is ~/Library/ApplicationSupport/Titanium/modules/iphone\r\n# Open Studio\r\n# Create a new 2-tabbed app, iPhone/iPad only\r\n# Add the module to the application from the tiapp.xml editor\r\n# Drop to the command line. 'ti build -p iOS'.\r\n\r\nThe app will fail to build, unable to find the ChasePaymentech framework\r\n\r\nh4. Fix the Xcode project\r\n# Open builds/iphone/.xcodeproj\r\n# Follow the instructions in the Paymenttech document to both link the framework in the application, and then to copy the framework during the build process.\r\n## Place the framework library in a folder accessible to your application.\r\n## Select Project Setting and Build Phase. Click on “Link Binary With Libraries” section. Then press “+” button to add the framework.\r\n## Click on “Add Other…” and choose ChasePaymentech.framework from the physical location in step 1.\r\n## Click “Copy Files”, ensure “Framework” is selected in “Description” drop-down. Click “+” as indicated below.\r\n## Select “ChasePaymentech.framework” under “frameworks”.\r\n## Under “Project Navigator”, within “Frameworks”, “ChasePaymentech.framework” would have been added.\r\n\r\nAttempt to build the application, you will get the error about \"ld: embedded dylibs/frameworks are only supported on iOS 8.0 and later\"\r\n\r\nh4. To Fix it\r\nBuild Settings > iOS Deployment Target. Update this to 8.0\r\n\r\nApp builds successfully...sometimes. When it fails, it appears to fail because it can't find the Chase framework. This suggests that the framework isn't being copied in time to the correct output location before linking.", "attachment": [], "flagged": false, "summary": "iOS: Add support for Swift libraries in native modules", "creator": { "name": "iotashan", "key": "iotashan", "displayName": "Shannon Hicks", "active": true, "timeZone": "America/Chicago" }, "subtasks": [], "reporter": { "name": "iotashan", "key": "iotashan", "displayName": "Shannon Hicks", "active": true, "timeZone": "America/Chicago" }, "environment": null, "closedSprints": [ { "id": 1018, "state": "closed", "name": "2018 Sprint 07 SDK", "startDate": "2018-03-25T21:59:36.637Z", "endDate": "2018-04-08T21:59:00.000Z", "completeDate": "2018-04-08T17:55:14.467Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "329130", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "This is not a duplicate. One is using Swift code directly in the library, the other is referencing a Swift library as a dependency.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-23T04:16:37.000+0000", "updated": "2014-10-23T04:16:37.000+0000" }, { "id": "329132", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I have added my steps to the above description. If they are incorrect, please edit.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-23T04:46:30.000+0000", "updated": "2014-10-23T04:46:30.000+0000" }, { "id": "329153", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Ingo , the work around is not 100% true. There seems to be a race condition when doing this... my slower mac mini has no issue with doing this, but running on my MBPr fully specked out it works 1 in 10 times or so. The rest of the time I get an error that the SDK (Chase in this instance) can not be found.", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-23T12:38:47.000+0000", "updated": "2014-10-23T12:38:47.000+0000" }, { "id": "329160", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~mattapperson] When it does work, is the workaround correct? I am more concerned with the general overall flow so that we can then update the tooling to accommodate this.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-23T14:30:38.000+0000", "updated": "2014-10-23T14:30:38.000+0000" }, { "id": "329161", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "It is yes... but there must be something the tooling needs to wait for at some point to prevent the race condition.", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-23T14:32:13.000+0000", "updated": "2014-10-23T14:32:13.000+0000" }, { "id": "329163", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Okay, that's good to know. That means it's a simpler CLI/build process change than something that relates to how we build/link libraries.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-23T14:37:50.000+0000", "updated": "2014-10-23T14:37:50.000+0000" }, { "id": "330106", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "The reason for the issue is:\r\nhttp://aerogear-dev.1069024.n5.nabble.com/aerogear-dev-Swift-Frameworks-Static-libs-and-Cocoapods-td8456.html\r\n\r\nSo basically even if we get it to copy without issue, the fact that ti modules compile to a static lib is a no go at this point...", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-30T19:08:20.000+0000", "updated": "2014-10-30T19:08:20.000+0000" }, { "id": "330113", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "So in other words, once you add #import \r\n the module can no longer compile. Or when it does it results in the app crashing immediately \r\n", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-30T19:37:51.000+0000", "updated": "2014-10-30T20:12:15.000+0000" }, { "id": "330181", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "NOTE:\r\nTo make the titanium project find the third party library, add the path to the module.xcconfig file. If the module is at the project level (not at the titanium sdk level), the module.xcconfig should look like this:\r\n{code}\r\nOTHER_LDFLAGS=$(inherited) -F$(SRCROOT)/../../modules/iphone/ti.test/1.0.0/platform/iphone -framework ChasePaymentech\r\n{code}", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-10-31T10:39:44.000+0000", "updated": "2014-10-31T10:39:44.000+0000" }, { "id": "330184", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Pedro, Yes you are correct, but that is not the issue here.\r\n\r\nMy module.xcconfig looks like this FWIW\r\nFRAMEWORK_SEARCH_PATHS=$(SRCROOT)/../../modules/iphone/ti.passbook.paymentech/1.0.0/platform /Library/Application\\ Support/Titanium/modules/iphone/ti.passbook.paymentech/$1.0.0/platform ~/Library/Application\\ Support/Titanium/modules/iphone/ti.passbook.paymentech/1.0.0/platform\r\n\r\nOTHER_LDFLAGS=$(inherited) -framework ChasePaymentech\r\n", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-31T12:14:33.000+0000", "updated": "2014-10-31T12:14:33.000+0000" }, { "id": "330189", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "I know :) Just giving out a hint to make the \"including third party libs\" a bit easier.\r\nI'm looking into this right now. I think the first thing we need to do is make the module a dynamic library, that's the first step and that's what I'm working on.", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-10-31T13:12:16.000+0000", "updated": "2014-10-31T13:12:16.000+0000" }, { "id": "330191", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I'm not convinced that the requirement for a module being a dynamic library is an actual architectural requirement, and may instead be a decision Apple has decided to enforce. Please take a look at http://andelf.github.io/blog/2014/06/25/write-swift-module-with-swift-cont/ (you're going to need to use Google translate here).", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-31T14:06:05.000+0000", "updated": "2014-10-31T14:06:05.000+0000" }, { "id": "330197", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I think I might have a path forward without having to do anything too radical... details forthcoming after some more tests", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-31T14:34:01.000+0000", "updated": "2014-10-31T14:34:01.000+0000" }, { "id": "330198", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "OK so when building the module we still have 2 issues: \r\n- The module Xcode proj displays errors like crazy saying it cant see the frameworks headers\r\n- ./build.py will sometimes error out with the same issue.\r\n\r\nWe can build if we keep deleting the modules build dir... not sure the reason for the issue there.\r\nHowever once we do that and follow the fix steps above PLUS in the general tab of the apps xcode proj, under \"embedded binaries\" we link to the framework we are able to successfully build an app with a module using a swift framework.\r\n", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-31T14:42:00.000+0000", "updated": "2014-10-31T14:42:00.000+0000" }, { "id": "330699", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "I'm able to build the module without errors. This is the way the module.xcconfig looks on my end\r\n{code}\r\nFRAMEWORK_SEARCH_PATHS=$(SRCROOT)/../../modules/iphone/ti.testmodule/1.0.0/platform/iphone /Library/Application\\ Support/Titanium/modules/iphone/ti.testmodule/1.0.0/platform/iphone ~/Library/Application\\ Support/Titanium/modules/iphone/ti.testmodule/1.0.0/platform/iphone\r\nOTHER_LDFLAGS=$(inherited) -framework ChasePaymentech\r\n{code}\r\nThen, I placed the framework in the \"platform/iphone\" folder at the root of the module folder, create it if not there. After that, delete the \"build\" folder, build the module normally.\r\n\r\nOnce that's done, introduce the module to your Titanium app the same way you've always done it. Add this to tiapp.xml\r\n{code}\r\n\r\n\t...\r\n\t...\r\n\t8.0\r\n\r\n{code}\r\nRun it from Studio, and it will crash. This is what I did to \"fix\" it.\r\n\r\n1. Open the generated Xcode project\r\n2. Drag the third party framework (ChasPaymentech.framework) to Xcode, to the “Frameworks” folder in your project\r\n3. Click on the project name, blue icon on the left bar, so that the App properties appear in the middle section of Xcode\r\n4. Click on the target you’re building, the one without \"-ipad” and without \"-univesal\"\r\n5. Drag the framework, that you previously dragged into Xcode, to the \"Embedded Binaries” section of the app properties\r\n6. Click on the project, on top of the targets, and make sure that the “iOS Deplyment Target” is selected to iOS 8\r\n7. Run the app\r\n\r\nGive this a try and let me know if it works for you.", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-11-04T18:38:29.000+0000", "updated": "2014-11-04T18:38:29.000+0000" }, { "id": "330700", "author": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Yes this is what I have been doing to get through this project.", "updateAuthor": { "name": "mattapperson", "key": "mattapperson", "displayName": "me@gmail.com", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-11-04T18:42:33.000+0000", "updated": "2014-11-04T18:42:33.000+0000" }, { "id": "436553", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Work in progress in TIMOB-17887, scheduling for 8.0.0. ", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-04-05T19:23:53.000+0000", "updated": "2018-04-05T19:23:53.000+0000" }, { "id": "440014", "author": { "name": "emerriman", "key": "emerriman", "displayName": "Eric Merriman ", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Closing as a duplicate. If this is in error, please reopen.", "updateAuthor": { "name": "emerriman", "key": "emerriman", "displayName": "Eric Merriman ", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-08-06T17:41:11.000+0000", "updated": "2018-08-06T17:41:11.000+0000" } ], "maxResults": 21, "total": 21, "startAt": 0 } } }