With the new Xcode, I see File->New->Swift Package. And this works very differently than the past. Specifically, it gives you a straight folder, no Xcode project, and it does not have build targets. You cannot add targets inside it either.
Is it possible to distribute an example app inside a Swift PM module? And, is this the type of coding style that the AlamoFire project would look favorably on?
The full git repo is downloaded, so anything in there is technically accessible. The complication is the files are locked, so opening an Xcode project/workspace results in numerous "this project is locked" dialogs.
I am trying to figure out how the module and the example gets put into the same GitHub repo.
So is the idea to first make the package (File->New->Swift Package) and then go back in to make a project (File->New->Project) and put it in the same folder and then make the project dependent on the package (File->Swift Packages->Add Package Dependency)?
I spent my Apple Developer Incidents on getting that recipe right, and I maintain the file. So I am definitely looking to make this perfect so others can use it.
FYI I can only comment on my understanding of SPM, not what those behind AlamoFire would prefer.
One thing that tripped me up originally with Xcode's SPM integration is that a module is not an project so it it can't have targets. It doesn't build to anything, it's built by things. What Xcode 11 added support for is being able to work with a package using similar tools as a project, with Package.swift being analogous to the .xcproj file. That's what's happening when you do New Swift Package or when you open Package.swift directly.
SPM doesn't know/care about any project files, so as long as Package.swift is in the root directory, you're free to use a project or workspace however you like. Same for example projects and/or Playgrounds. If you're working with a project/workspace I believe you can either import the package locally into your project, or included the files manually.
What things ought to be done/included (readme, playground, example app, etc.) IMO depends on the complexity of the library you're developing. AF will choose a structure that fits their project. I don't know what they would recommend.
You should know that Alamofire's SPM support is just the bare minimum required to support building. We don't do any testing through SPM (since it doesn't support 2/3 of the testable platforms we support) and we don't use SPM as the basis of our project file. Alamofire predates the existence of SPM by over a year, and it was many years more before it could even be built using SPM. Our project layout hasn't changed much since the project was created and is only purposeful so far as supporting various things we've needed over time, like a docs folder for HTML documentation, since that's where GitHub requires it to generate a documentation site. It's unfortunate that SPM downloads all of this, as it's largely a waste of space.
But overall, I think supporting demo apps, documentation, and other meta project details in SPM is a good idea. Feel free to make a pitch for them, but I don't anticipate much overt support from the SPM developers.
Open Xcode, open the iOS Example, File->Swift Packages->Reset Package Caches
This seems to work, the iOS project is actually connected to the local copy. There is the unfortunate effect that only released versions of the module (i.e. Git tagged) are seen by the example project and surely this will cause somebody confusion during development of the library.
I would also rename the folder "iOS Example/iOS Example" to "iOS Example/Source" because a believe that is best practice, it is adopted by AlamoFire. There a multiple steps to do that and there is an Xcode bug, all documented in RECIPE.md at the top of the original post.
This is a possible path forward for me, for swift5-module-template, for all my projects, and for CocoaPods.
For AlamoFire and projects with tvOS targets and other advanced build settings it seems the old way (using *.xcworkspace) will be necessary for the foreseeable future.
This brings me to a head. I don't want to adopt this new way as a template if there is not a strong, real-world project like AlamoFire doing it this way ^^^.
Unless you want it referring to tagged versions, having it use the adjacent state is probably simpler. (If you do want to refer to a stable version, you would probably be better of referring to a canonical remote repository, since tags donât necessarily propagate between clones.)
Start with a valid swift package. ($ swift package init in a directory will create one if you are starting from scratch.)
Create an Xcode project somewhere in the repository. (Or move an existing project there.) I usually collect such things in an Xcode/ subdirectory, so that it wonât interfere with swift package generate-xcodeproj if I need to use it. (There are still a few corner cases where doubleâclicking the package manifest doesnât quite work properly; they will likely be fixed over time though.)
Drag the package directoryânot the manifestâfrom finder into Xcode. Xcode will then contain a reference to the package as a relative path. (If it asks to create a workspace, because none exists yet, make sure you also put that into the repository.)
Xcode targets can then depend on package products under âGeneral â Frameworks, Libraries, and Embedded Contentâ.
I hadnât noticed that. Under a particular package, Xcode also lists any miscellaneous files or directories irrelevant to the package but still located in its repository (such as LICENSE.md). It is in this section that those files appear. They arenât used and donât interfere with anything, but their appearance could be perceived as unwanted noise or as a source of confusion.
I think the duplicate file listing is acceptable. I posted a step-by-step receipt for how to create a Swift package and wire it up with an example iOS app here:
Surely using Swift Package Manager is now best practice for nearly all situations. And I recommend that anybody starting a Swift project with reusable code to use that ^^ repository as a starting point.
It also includes workarounds and notes for several Xcode issues. AND it even provides a workaround for include a resource in a Swift Package.
@fulldecent We are using similar approach in one of the projects, where inside SPM module we have source and an Example project very similar to your setup. However, we having some wired issues with assets, where if we change an asset i.e. image or we change label text on storyboard and run the app example app don't get updated assets. Unless we clean build folder and run the app again.
Did you come across this kind of issues or you have any idea what would be the problem?
Thanks.
We have also seen this issue and we have a dirty workaround for assets in SPM modules. We wrapped an image file as a a base64-encoded string encoded as a variable in Swift. That template is still actively maintained as we update for newer Swift/Xcode versions and find new tricks.
@fulldecent Thanks for the reply. I have one more question regarding the Storyboards, did you had same issue with storyboards? We seeing that if we change the storyboard in the module e.g. updating the label text on the storyboard and run the app using cmd + r app will not show latest changes until till we clean and build again.