Extracting a framework

Now that we have our code properly and satisfactorily refactored, we can move on to the next step: making the actual framework and using it in a project.

To create our new FuturesAndPromises framework, perform the following steps:

  1. Create a new directory, called FuturesAndPromises
  2. Run cd FuturesAndPromises and then swift package init --type library
  3. Copy the four source files you created into Sources/FuturesAndPromises
  4. Run swift build to check that your code compiles correctly; if not, fix all the errors until it compiles successfully
  5. If you have created a test file, copy it to Tests/FuturesAndPromisesTests and run swift test

If your swift build step completed without errors, you have successfully created your FuturesAndPromises framework. Now, you can use it in other projects. For example, we could modify our previous swURL example so it uses FuturesAndPromises to manage its network operations instead of relying on callbacks. To do so, we need to perform the following:

We saw earlier that adding a dependency to an SPM package is as easy as listing it in Package.swift, where you can add its Git repository URL under the dependencies section. In our current case, we do not have any Git URL available, since FuturesAndPromises is a local framework we have just created that has not been pushed yet to, for example, GitHub. It turns out, though, that SPM also supports local Git repositories, so this will not be a big problem. But, we will need to create a Git repository for our FuturesAndPromises framework and create a version tag for it, so SPM can retrieve it.

Creating a Git repository for FuturesAndPromises is quite an easy task. Just cd to the directory containing FuturesAndPromises files and run the following commands:

Now, you can open the Package.swift file in swURL and add the dependency to FuturesAndPromises. Open that file in your preferred editor and make sure its dependencies section looks similar to the following, where you will take care of setting the correct relative or absolute path to your FuturesAndPromises location:

    dependencies: [
.package(url: "../FuturesAndPromises", from: "1.0.0"),
],

Now, if you run swift build, you will see the following output:

Updating https://github.com/google/promises.git
Fetching /Users/sergio/tmp/packt-book/Chap13-code/FuturesAndPromises
Completed resolution in 0.43s
Removing https://github.com/google/promises.git
Cloning /Users/sergio/tmp/packt-book/Chap13-code/FuturesAndPromises
Resolving /Users/sergio/tmp/packt-book/Chap13-code/FuturesAndPromises at 1.0.0
warning: dependency 'FuturesAndPromises' is not used by any target
You may be puzzled by the references to the Google Promises framework. As you may remember, we added it as a dependency to our initial swURL implementation. The latest changes to Package.swift we just outlined removed that dependency, so SPM cleaned it up!

The final line in the output of swift build is a warning telling us we are not using FuturesAndPromises anywhere. This will be fixed when we will complete our swURL implementation. This will require creating a wrapper for URLSession.dataTask and rewriting the swURL.jsonRequest method so it uses a promise. We already did something very similar in Chapter 12, Futures, Promises, and Reactive Programming, so we will leave this as exercise to the reader.

Once you are done rewriting swURL to use FuturesAndPromises, the next step is to generate a convenience Xcode project out of it. As you know, we mentioned that this is required if you want to integrate your Swift package into another Xcode project. In our case, having modified the swURL framework, this step will have the effect of bringing all of those changes to any Xcode project that uses it. This is another benefit of using SPM with Xcode.

Of course, you can also integrate the FuturesAndPromises framework into a new Xcode project independently from swURL. The steps to do so are the same as those outlined when we integrated swURL into an Xcode project, so you should have no trouble carrying this through as an exercise.

As a final note, with SPM, there is an easy way to share your frameworks across your project, within your organization, or with the open source community. Indeed, all is needed is publishing them to GitHub, BitBucket, or any other cloud-based Git provider. Of course, you will need your account with that provider to be private if you do not want your framework to become available to the whole open source community.