Import Swift Package in Xcode11 - swift

I'm trying to import an SPM package in Xcode11. I can fetch the library and see it in the project as Swift Package Dependencies but when trying to import, Xcode doesn't find it.
I read that the problem could be custom configurations and not the standard e.g. Debug.
Does anyone know how to solve this without renaming the configuration names?

The best advice at the moment is this post on the Swift forums where Ankit says:
This is a known issue that Apple folks are tracking internally. Currently, Swift packages default to the "Release" configuration when anything other than Debug and Release is used. In theory, adding $(BUILD_DIR)/Release to SWIFT_INCLUDE_PATHS build setting for the custom configurations should work around this issue but it can lead to some weird errors in case something unexpected gets picked from that directory.

Related

Conditional imports and Dart_VLC

I'm working on a Web/Windows/Android app and to play a soundbite I am using just_audio. However, just_audio for windows is deprecated.
To work around this I want to use Dart_VLC for windows only. However, if it is imported at all, the app will crash with the following error (full trace https://pastebin.com/qNrW3ghK):
LateInitializationError: Field 'dynamicLibrary' has not been initialized.
I've found that conditional imports resolve this to an extent.
import 'metronome_finder.dart'
if (dart.library.io) 'windows_metronome.dart'
if (dart.library.js) 'generic_metronome.dart';
This (and an abstract, two classes, and a stub) works for Web/Windows. However, on android, it appears dart.library.io is loaded and dart_vlc will be imported as well, crashing the app with the above error. Is there a way to import the windows metronome only on windows (and thus dart_vlc) and generic on all other platforms?
Alternatively is there another cleaner way to resolve this issue?
I've also asked this question on reddit and thanks in part to /u/bsutto there is now a solution (or a workaround).
I've written an example based on my own project. The core revelation here is that the import of dart_vlc breaks compilation on web, but the initialization of dart_vlc crashes during runtime. As a result it is possible to use conditional imports to direct web towards just_audio; and a runtime Platform.isWindows check to redirect android to JustAudio.
The major downside to this is that the entirety of dart_vlc is compiled into the andoird app as well, I think. Please correct me if I am wrong.

What is the correct way to include Playgrounds in a Swift Package?

When I publish a Swift Package, I like to include some Playgrounds to show examples of how to use the package. Prior to Swift 5.4, I was able to do this in a relatively straightforward way, but now none of my Playgrounds ever sees the contents of my package module. It doesn't make any sense to me.
I've followed the exact pattern illustrated by Apple's own WWDC videos, which is to have a Playgrounds/ folder as a peer to your Sources/ folder, and then just import the package module.
The import works, but the Playground always reports that it cannot find any of the types from inside the module. They are all marked public, and as I mentioned before, these used to work just fine.
This doesn't work for me in Swift 5.4 or 5.5, in Xcode 12.5 or 13 Beta.
I assume there must be some setting or configuration I am not understanding. Can somebody please explain the best practice here?
For reference, here is one of my simple Swift Packages that has Playgrounds that currently do not work:
https://github.com/dunesailer/Wordsmith
EDIT: It gets even stranger. I have a different Swift Package structured what appears to me to be the exact same way, but its Playgrounds work fine. Whaaat? That one is here:
https://github.com/dunesailer/Aesthete
If you move/ delete the folders Chemical Names, Work Titles and Person Names inside Playgrounds/, all the playgrounds work fine. It looks like Xcode doesn't support folders in Playgrounds/ (/ it's a bug).
So to work around this issue, just put all your playgrounds in the same folder.
EDIT: It looks like this works inconsistently. I've submitted a bug report/ Feedback for Developer Tools in Feedback Assistant.
A longer term workaround is to use DocC (arrived in Xcode 13 beta), which will support more advanced tutorials/ articles in the repo.
Use workspace.
(Xcode: File: New: Workspace)
You use it as "container" for both your package, playground (or app target for that matter). The important thing is to add each of these to the workspace by using "Add files to ..." button in the lower-left section of the Xcode, and from there on, open the .xcworkspace file:
to edit your package
to run playground file.
You can follow instructions from here.
https://stackoverflow.com/a/67580251/13292535

cocoapods in library not found in app extension

I have an app and accompanying extension, with a cocoa touch framework in the same project containing most of the shared code. The problem I'm faced with is that the cocoapods that the framework depends on are not found when compiling the app extension. The framework target compiles just fine, but when I compile the extension target I get a bunch of 'unresolved identifier' errors.
The problem does not seem to be that the framework is not being linked as I can access classes defined within it just fine from the extension. I have looked at other questions such as this one, but nothing I've seen seems to solve my problem.
Any help would be greatly appreciated!
EDIT:
The problem was solved by creating a separate bridging header for the extension. Hope this can help someone else!
EDIT 2:
Unfortunately this solution causes the warning
Class AFHTTPRequestOperation is implemented in both path/myFramework and
path/myWidget.appex/myWidget. One of the two will be used. Which one is undefined.
An explanation of why this happens and how to avoid it would by much appreciated.
Your extension needs its own bridging header. Add one, import the cocoapod, follow this answer if you need to here, go.

Building pure Swift Cocoa Touch Framework

I'm exploring Swift with Xcode-6 and so far so good although I think the new collections need a little bit of work as I've managed to break the compiler a few times.
Problem is I'm now stuck trying to create the framework package to then use in another project. The project builds without issue and all tests pass successfully. When I go to create Archive (which I assume is what is required) I receive the error:
:0: error: underlying Objective-C module 'Sample' not found
Now I assume this has something to do with the contents of my Sample.h which tells me
// In this header, you should import all the public headers of your framework using statements like #import <Sample/PublicHeader.h>
which is fine except I have only used swift enums, structs and classes for this framework so therefore no .h files exist.
Can anyone shed some light on this one as I can't find any documentation available yet?
EDIT (7/27/2018)
The information in the answer below may no longer be accurate. Your mileage may vary.
I sat down with an engineer and asked this exact question. This was their response:
Xcode 6 does not support building distributable Swift frameworks at this time and that Apple likely won't build this functionality into Xcode until its advantageous for them to do so. Right now, Frameworks are meant to be embedded in your app's project, rather than distributed. If you watch any of the session videos or see the sample projects, this is always the arrangement. Another reason is that Swift is very new and likely to change. Thus your Swift-based framework is not guaranteed to work on the platform you originally built it on.
Slight Update
The engineer mentioned that it's not impossible to make a framework for distribution, just that it's not supported.
I was able to get past the error by going to the target for the framework and on the Build Phases tab under Headers, remove the MyFramework.h file
However I was getting the "Underlying Objective-C module not found" error when I was using a framework to share code between a containing app and an app extension, both of which were pure Swift.
Assuming you are creating a truly pure Swift module, you must disable the Objective-C Compatibility Header and any generated interface headers so the compiler doesn't go off assuming it can find an Objective-C module for the framework.
Do Not remove your public framework header. You'll get a module-map warning at link time if you do.
You might find this useful: Creation of pure swift module
In short: it's possible to make static framework, but there is one issue: it doesn't work in end user' project if "ProjectName-Swift.h" header included.
But, it works fine if you use only swift.
I think it's a bug in XCode 6, or that Apple does not allow archiving the Framework from XCode while in beta.
If you compile to profile XCode generates the framework correctly. (See the Release folder created in DerivedData)

Three20 dependency problem

I checked out the three20 source and was trying to follow this
guide to build an iphone app using the framework. Within this guide, Templates are used which I checked out too. They ought to compile properly, but I get the following error:
File /Users/myUser/programming/three20/src/build/Debug-iphonesimulator/libThree20.a depends on itself. This target might include its own product.
Did anyone ever solve that issue? I read it was about including something you want to create which is not possible. Anyway any solution I found did not help here.
I actually did not even change anything! Any ideas?
Okay I fixed this by opening the three20.xcodeproj and unchecking the target box for libThree20.a (while leaving it checked in my project that is using three20).
This has at least got me building and running, will report if any problems come up later.