Skip to content

Commit

Permalink
Merge pull request #120 from niscy-eudiw/refactor
Browse files Browse the repository at this point in the history
Refactor RequestItems and ElementViewModel structures
  • Loading branch information
phisakel authored Nov 19, 2024
2 parents d745d4f + 9f677f5 commit b58b1bf
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 21 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: Swift Build

on: [push]
on:
pull_request:
types: [opened, reopened]
push:
branches: ['main']
tags: [ v* ]
jobs:
build:
runs-on: macos-latest
Expand Down
22 changes: 11 additions & 11 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "ebf47c2682782005cbaf1f28ff387c17a3cad1d91fcba1d59b4cd31b98367167",
"originHash" : "751cb5694cd2e9d547658bb43e87ff87c1bec7fe7c5e3372d7734d8835c52c02",
"pins" : [
{
"identity" : "blueecc",
Expand Down Expand Up @@ -33,8 +33,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-iso18013-data-transfer.git",
"state" : {
"revision" : "2f00a68370572f914997706a29d15d6fc0b89ceb",
"version" : "0.3.3"
"revision" : "900416bcab3e95a17dea2fbf224210521c5b68d6",
"version" : "0.3.7"
}
},
{
Expand Down Expand Up @@ -123,8 +123,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/KittyMac/Sextant.git",
"state" : {
"revision" : "52a77d0bce0210cf9557faef7fd0adb9a6da02fb",
"version" : "0.4.31"
"revision" : "b2141d4a693e2a768720534009cb621252be39a0",
"version" : "0.4.33"
}
},
{
Expand All @@ -150,17 +150,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-asn1.git",
"state" : {
"revision" : "df5d2fcd22e3f480e3ef85bf23e277a4a0ef524d",
"version" : "1.2.0"
"revision" : "7faebca1ea4f9aaf0cda1cef7c43aecd2311ddf6",
"version" : "1.3.0"
}
},
{
"identity" : "swift-certificates",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-certificates.git",
"state" : {
"revision" : "2f797305c1b5b982acaa6005d8a9f970cc4e97ff",
"version" : "1.5.0"
"revision" : "1fbb6ef21f1525ed5faf4c95207b9c11bea27e94",
"version" : "1.6.1"
}
},
{
Expand All @@ -177,8 +177,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-crypto.git",
"state" : {
"revision" : "ffca28be3c9c6a86a579949d23f68818a4b9b5d8",
"version" : "3.8.0"
"revision" : "06dc63c6d8da54ee11ceb268cde1fa68161afc96",
"version" : "3.9.1"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.3"),
.package(url: "https://github.com/crspybits/swift-log-file", from: "0.1.0"),
.package(url: "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-iso18013-data-transfer.git", exact: "0.3.3"),
.package(url: "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-iso18013-data-transfer.git", exact: "0.3.7"),
.package(url: "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage.git", exact: "0.3.0"),
.package(url: "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-siop-openid4vp-swift.git", exact: "0.6.0"),
.package(url: "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-openid4vci-swift.git", exact: "0.7.0"),
Expand Down
10 changes: 9 additions & 1 deletion Sources/EudiWalletKit/Services/Openid4VpUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Logging
import PresentationExchange
import MdocDataModel18013
import MdocSecurity18013
import MdocDataTransfer18013
/**
* Utility class to generate the session transcript for the OpenID4VP protocol.
*
Expand Down Expand Up @@ -92,13 +93,20 @@ class Openid4VpUtils {
guard let fc = inputDescriptor.formatContainer else { logger?.warning("Input descriptor with id \(inputDescriptor.id) is invalid "); continue }
guard fc.formats.contains(where: { $0["designation"].string?.lowercased() == "mso_mdoc" }) else { logger?.warning("Input descriptor with id \(inputDescriptor.id) does not contain format mso_mdoc "); continue }
let docType = inputDescriptor.id.trimmingCharacters(in: .whitespacesAndNewlines)
let kvs: [(String, String)] = inputDescriptor.constraints.fields.compactMap(\.paths.first).compactMap { Self.parsePath($0, pathRx: pathRx) }
let kvs = inputDescriptor.constraints.fields.compactMap { Self.parseField($0, pathRx: pathRx) }
let nsItems = Dictionary(grouping: kvs, by: \.0).mapValues { $0.map(\.1) }
if !nsItems.isEmpty { res[docType] = nsItems }
}
return res
}

static func parseField(_ field: Field, pathRx: NSRegularExpression) -> (String, RequestItem)? {
guard let path = field.paths.first else { return nil }
guard let nsItemPair = parsePath(path, pathRx: pathRx) else { return nil }
return (nsItemPair.0, RequestItem(elementIdentifier: nsItemPair.1, intentToRetain: field.intentToRetain ?? false, isOptional: field.optional ?? false))
}

/// parse path and return (namespace, itemIdentifier) pair e.g. example path: "$['eu.europa.ec.eudiw.pid.1']['family_name']"
static func parsePath(_ path: String, pathRx: NSRegularExpression) -> (String, String)? {
guard let match = pathRx.firstMatch(in: path, options: [], range: NSRange(location: 0, length: path.utf16.count)) else { return nil }
let r1 = match.range(at:1);
Expand Down
2 changes: 1 addition & 1 deletion Sources/EudiWalletKit/Services/PresentationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Foundation
import MdocDataTransfer18013

/// [Doc Types to [Namespace to Items]] dictionary
public typealias RequestItems = [String: [String: [String]]]
public typealias RequestItems = MdocDataTransfer18013.RequestItems

/// Presentation service abstract protocol

Expand Down
18 changes: 13 additions & 5 deletions Sources/EudiWalletKit/ViewModels/DocElementsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

import Foundation
import MdocDataModel18013
import MdocDataTransfer18013

/// View model used in SwiftUI for presentation request elements
public struct DocElementsViewModel: Identifiable, Sendable {
Expand All @@ -27,12 +28,13 @@ public struct DocElementsViewModel: Identifiable, Sendable {
public var elements: [ElementViewModel]
}
extension DocElementsViewModel {
static func fluttenItemViewModels(_ nsItems: [String:[String]], valid isEnabled: Bool, mandatoryElementKeys: [String]) -> [ElementViewModel] {
static func fluttenItemViewModels(_ nsItems: [String:[RequestItem]], valid isEnabled: Bool, mandatoryElementKeys: [String]) -> [ElementViewModel] {
nsItems.map { k,v in nsItemsToViewModels(k,v, isEnabled, mandatoryElementKeys) }.flatMap {$0}
}

static func nsItemsToViewModels(_ ns: String, _ items: [String], _ isEnabled: Bool, _ mandatoryElementKeys: [String]) -> [ElementViewModel] {
items.map { ElementViewModel(nameSpace: ns, elementIdentifier:$0, isMandatory: mandatoryElementKeys.contains($0), isEnabled: isEnabled) }
static func nsItemsToViewModels(_ ns: String, _ items: [RequestItem], _ isEnabled: Bool, _ mandatoryElementKeys: [String]) -> [ElementViewModel] {
// default for intent-to-retain is false, default for isOptional is true
items.map { ElementViewModel(nameSpace: ns, elementIdentifier: $0.elementIdentifier, isOptional: $0.isOptional ?? !mandatoryElementKeys.contains($0.elementIdentifier), intentToRetain: $0.intentToRetain ?? false, isEnabled: isEnabled) }
}

static func getMandatoryElementKeys(docType: String) -> [String] {
Expand Down Expand Up @@ -76,12 +78,18 @@ public struct ElementViewModel: Identifiable, Sendable {
public var id: String { "\(nameSpace)_\(elementIdentifier)" }
public let nameSpace: String
public let elementIdentifier: String
public let isMandatory: Bool
public let isOptional: Bool
public let intentToRetain: Bool
public var isEnabled: Bool
public var isDisabled: Bool { !isEnabled }
public var isSelected = true
}

extension Array where Element == ElementViewModel {
var nsDictionary: [String: [String]] { Dictionary(grouping: self, by: \.nameSpace).mapValues { $0.map(\.elementIdentifier)} }
var nsDictionary: [String: [RequestItem]] {
Dictionary(grouping: self, by: \.nameSpace)
.mapValues {
evm in evm.map { RequestItem(elementIdentifier: $0.elementIdentifier, intentToRetain: $0.intentToRetain, isOptional: $0.isOptional) }
}
}
}
11 changes: 11 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## v0.7.7
- Fix issue [#118](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-kit/issues/118)
### Breaking changes
- `RequestItems` is now a dictionary with a key of type `String` (doc-type) and a value of type `[String: [RequestItem]]` (namespace to request items)
- `RequestItem` is a struct with the following properties: `elementIdentifier`, `intentToRetain` and `isOptional`
```swift
public typealias RequestItems = [String: [String: [RequestItem]]]
```
- ElementViewModel: `public var isMandatory: Bool` is removed
- ElementViewModel: `public var isOptional: Bool` is added (opposite of `isMandatory`)

## v0.7.4
- Update Package.resolved and Package.swift with new versions for openid4vci, openid4vp

Expand Down

0 comments on commit b58b1bf

Please sign in to comment.