# Swift Package Manager: understand resolve, reset and update

I will explain the operations

- resolve
- reset
- update

and how these commands affect a Swift Package. I will further show how to invoke those operations from the command line or within Xcode.

I use the following example: a package with a single package dependency pinned to an **exact** version (Alamofire 5.4.0). The `Package.swift` manifest file:

```Swift
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Package1",
    products: [
        .library(
            name: "Package1",
            targets: ["Package1"]),
    ],
    dependencies: [
        .package(url: "https://github.com/Alamofire/Alamofire", .exactItem("5.4.0")),
    ],
    targets: [
        .target(
            name: "Package1",
            dependencies: [
                "AlamoFire"
            ])
    ]
)
```

Initially the package, created with `swift package init` command, had no `Package.resolved` file.

When I opened the package in Xcode and added the following line in `Package.swift`

```swift
    dependencies: [
        .package(url: "https://github.com/Alamofire/Alamofire", .exactItem("5.4.0")),
    ],
```

then Xcode automatically started the dependency resolution and created a `Package.resolved` file in the top level of the package to record the result of the dependency resolution.

```Swift
{
  "pins" : [
    {
      "identity" : "alamofire",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/Alamofire/Alamofire",
      "state" : {
        "revision" : "9e0328127dfb801cefe8ac53a13c0c90a7770448",
        "version" : "5.4.0"
      }
    }
  ],
  "version" : 2
}
```

If I had edited the `Package.swift` file in a text editor, I would have had to manually trigger the dependency resolution. See the next chapter :)

# Resolve

`swift package resolve`

> The `swift package resolve` command resolves the dependencies, taking into account the current version restrictions in the `Package.swift` manifest and `Package.resolved` resolved versions file, and issuing an error if the graph cannot be resolved.

Source: [SPM Documentation](https://github.com/apple/swift-package-manager/blob/main/Documentation/Usage.md)

Key takeaway:
- no changes to an existing `Package.resolved` file !!
- creates a `Package.resolved` file if such does not exist.

The equivalent Xcode option is named "Resolve Package Versions".

![Resolve Package Versions](https://cdn.hashnode.com/res/hashnode/image/upload/v1647928204649/mcFEOJYPF.png)

When changing the `Package.manifest` to use a different version requirement, e.g.

```
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "https://github.com/Alamofire/Alamofire", .upToNextMinor(from: "5.4.0"))
    ],
```

and running `swift package resolve`, then you need to understand that this will not bring any changes! Because `Package.resolved` was not changed.

# Reset

`swift package reset`

This will reset the complete cache/build directory. For SPM (command-line) this will affect the `.build` folder.

The equivalent Xcode option is named "Reset Package Caches". This will affect the `SourcePackages` of the related folder in DerivedData.

![Reset Package Caches](https://cdn.hashnode.com/res/hashnode/image/upload/v1647926456903/vllHNzeBR.png)

# Update

The `swift package update` command will touch the `Package.resolved` file.

> Running `swift package update` updates all dependencies to the latest eligible versions and updates the Package.resolved file accordingly.

Source: [SPM Documentation](https://github.com/apple/swift-package-manager/blob/main/Documentation/Usage.md)

Remember I changed `Package.swift`  to use a newer version of my package dependency:

```
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "https://github.com/Alamofire/Alamofire", .upToNextMinor(from: "5.4.0"))
    ],
```

Running `swift package update` will change `Package.resolved`

```Swift
{
  "pins" : [
    {
      "identity" : "alamofire",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/Alamofire/Alamofire",
      "state" : {
        "revision" : "d120af1e8638c7da36c8481fd61a66c0c08dc4fc",
        "version" : "5.4.4"
      }
    }
  ],
  "version" : 2
}
```

and will download the new version.

In Xcode the same can be achieved from the top-level menu

![Update to Latest Package Versions](https://cdn.hashnode.com/res/hashnode/image/upload/v1647926466068/5rDqUCc6J.png)

but also in the Package Dependency pane you can select "Update Package" on an individual package.

![Update Package is the same as Update to Latest Package Versions](https://cdn.hashnode.com/res/hashnode/image/upload/v1647928115418/rMZIm31wo.png)

"Update Package" actually affects the whole `Package.resolved` file and is not truly package-specific.

# Summary

- If a download was interrupted then use "reset" and "resolve".

- If you want to use a newer version or you changed version requirements in your `Package.swift` file then use "update".
