Migrate to JWTDecode.swift v4
masterJWT protocol and the Claim struct, now conform to Sendable. Additionally, dictionary values for header, body, and Claim.rawValue have changed from Any to any Sendable.repository·master·Indexed 20 days ago
https://github.com/auth0/jwtdecode.swiftA lightweight Swift library for decoding JSON Web Tokens (JWT). It extracts headers, claims, and signatures from well-formed JWTs without performing cryptographic validation. The library is compatible with Swift 6 concurrency, with all public types conforming to Sendable. It supports installation via Swift Package Manager, CocoaPods, and Carthage.
JWT protocol and the Claim struct, now conform to Sendable. Additionally, dictionary values for header, body, and Claim.rawValue have changed from Any to any Sendable.When migrating to v3, ensure your project meets the following language requirements:
You can install JWTDecode.swift using Swift Package Manager, CocoaPods, or Carthage.
https://github.com/auth0/JWTDecode.swiftAdd this line to your Podfile:
pod 'JWTDecode', '~> 4.0'Then run pod install.
Add this line to your Cartfile:
github "auth0/JWTDecode.swift" ~> 4.0Then run carthage bootstrap --use-xcframeworks.
Before installing fastlane, ensure that the latest version of the Xcode command line tools is installed on your system.
xcode-select --installTo use the library, import the framework and use the decode(jwt:) function.
Important: This library does not validate the JWT signature; it only decodes the Base64URL encoded parts. Any well-formed JWT can be decoded.
All public types conform to Sendable, making the library fully compatible with Swift 6 concurrency.
import JWTDecode
// Decode the token
let jwt = try decode(jwt: token)Once a JWT is decoded, you can access its components and standard registered claims through specific properties on the JWT object.
| Part | Property |
|---|---|
| Header dictionary | jwt.header |
| Claims in JWT body | jwt.body |
| JWT signature | jwt.signature |
| Claim | Property |
|---|---|
| aud Audience | jwt.audience |
| sub Subject | jwt.subject |
| jti JWT ID | jwt.identifier |
| iss Issuer | jwt.issuer |
| nbf Not Before | jwt.notBefore |
| iat Issued At | jwt.issuedAt |
| exp Expiration Time | jwt.expiresAt |
The new .data property on a Claim allows you to retrieve the underlying JSON representation as Data. This is only available for complex claims (arrays and dictionaries). For primitive types (strings, integers, etc.), .data will return nil.
// Returns Data for arrays and dictionaries
let data = jwt["custom_object"].data
// Returns nil for primitives (use .string, .integer, etc. instead)
let primitiveData = jwt["email"].data // nilYou can retrieve custom claims using subscript syntax. The library provides several built-in type conversions or allows decoding directly into Decodable types.
string: String?boolean: Bool?integer: Int?double: Double?date: Date?array: [String]?data: Data?You can decode complex claims directly to a Decodable type, including using a custom JSONDecoder for specific configurations like keyDecodingStrategy.
// Retrieve a simple string claim
if let email = jwt["email"].string {
print("Email is \(email)")
}
// Decode a custom claim to a Decodable struct
struct Address: Decodable {
let street: String
let city: String
}
let address = try jwt["address"].decode(Address.self)
// Decode with a custom JSONDecoder configuration
struct User: Decodable {
let firstName: String
let lastName: String
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let user = try jwt["user_info"].decode(User.self, using: decoder)In v4, you can decode complex claims (like dictionaries or arrays) directly into a Swift type that conforms to Decodable using the .decode(_:using:) method on a Claim object.
struct Address: Decodable {
let street: String
let city: String
}
// Decode a custom claim
let address = try jwt["address"].decode(Address.self)
// With custom decoder configuration
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let userInfo = try jwt["user_info"].decode(UserInfo.self, using: decoder)If you directly access the rawValue property of a Claim, update the type annotation from Any? to (any Sendable)?.
// Before (v3)
let customClaim: Any? = jwt["custom"].rawValue
// After (v4)
let customClaim: (any Sendable)? = jwt["custom"].rawValueIf your code directly accesses the header or body properties of a JWT object, you must update the type annotations from [String: Any] to [String: any Sendable] to maintain compatibility with v4.
// Before (v3)
let header: [String: Any] = jwt.header
let body: [String: Any] = jwt.body
// After (v4)
let header: [String: any Sendable] = jwt.header
let body: [String: any Sendable] = jwt.body