Skip to content

Commit

Permalink
support multiple passes (#2349)
Browse files Browse the repository at this point in the history
  • Loading branch information
brindy authored Jan 19, 2024
1 parent 9a6efd7 commit f5401af
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 3 deletions.
21 changes: 21 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
85058370219F424500ED4EDB /* SearchBarExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F143C3451E4AA32D00CFDE3A /* SearchBarExtension.swift */; };
850ABD012AC3961100A733DF /* MainViewController+Segues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850ABD002AC3961100A733DF /* MainViewController+Segues.swift */; };
850ABD032AC4D46C00A733DF /* SuggestionTray.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 850ABD022AC4D46C00A733DF /* SuggestionTray.storyboard */; };
850F93DB2B594AB800823EEA /* ZippedPassKitPreviewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850F93DA2B594AB800823EEA /* ZippedPassKitPreviewHelper.swift */; };
8512EA4F24ED30D20073EE19 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8512EA4E24ED30D20073EE19 /* WidgetKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
8512EA5124ED30D20073EE19 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8512EA5024ED30D20073EE19 /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
8512EA5424ED30D20073EE19 /* Widgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8512EA5324ED30D20073EE19 /* Widgets.swift */; };
Expand Down Expand Up @@ -406,6 +407,7 @@
853A717820F645FB00FE60BC /* PixelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 853A717720F645FB00FE60BC /* PixelTests.swift */; };
853C5F5B21BFF0AE001F7A05 /* HomeCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 853C5F5A21BFF0AE001F7A05 /* HomeCollectionView.swift */; };
853C5F6121C277C7001F7A05 /* global.swift in Sources */ = {isa = PBXBuildFile; fileRef = 853C5F6021C277C7001F7A05 /* global.swift */; };
854007E72B57FC000001BD98 /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = 854007E62B57FC000001BD98 /* ZIPFoundation */; };
8540BBA22440857A00017FE4 /* PreserveLoginsWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8540BBA12440857A00017FE4 /* PreserveLoginsWorker.swift */; };
8540BD5223D8C2220057FDD2 /* PreserveLoginsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8540BD5123D8C2220057FDD2 /* PreserveLoginsTests.swift */; };
8540BD5423D8D5080057FDD2 /* PreserveLoginsAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8540BD5323D8D5080057FDD2 /* PreserveLoginsAlert.swift */; };
Expand Down Expand Up @@ -1447,6 +1449,7 @@
85058367219C49E000ED4EDB /* HomeViewSectionRenderers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewSectionRenderers.swift; sourceTree = "<group>"; };
850ABD002AC3961100A733DF /* MainViewController+Segues.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainViewController+Segues.swift"; sourceTree = "<group>"; };
850ABD022AC4D46C00A733DF /* SuggestionTray.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SuggestionTray.storyboard; sourceTree = "<group>"; };
850F93DA2B594AB800823EEA /* ZippedPassKitPreviewHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZippedPassKitPreviewHelper.swift; sourceTree = "<group>"; };
8512BCBF2061B6110085E862 /* global.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = global.swift; sourceTree = "<group>"; };
8512EA4D24ED30D20073EE19 /* WidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
8512EA4E24ED30D20073EE19 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -2680,6 +2683,7 @@
F4D7F634298C00C3006C3AE9 /* FindInPageIOSJSSupport in Frameworks */,
85D598872927F84C00FA3B1B /* Crashes in Frameworks */,
D664C7DD2B28A02800CBFA76 /* StoreKit.framework in Frameworks */,
854007E72B57FC000001BD98 /* ZIPFoundation in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -3313,6 +3317,7 @@
3132FA2527A0784600DD7A12 /* FilePreviewHelper.swift */,
3132FA2927A0788F00DD7A12 /* QuickLookPreviewHelper.swift */,
3132FA2727A0788400DD7A12 /* PassKitPreviewHelper.swift */,
850F93DA2B594AB800823EEA /* ZippedPassKitPreviewHelper.swift */,
);
name = FilePreview;
sourceTree = "<group>";
Expand Down Expand Up @@ -5689,6 +5694,7 @@
F42D541C29DCA40B004C4FF1 /* DesignResourcesKit */,
0238E44E29C0FAA100615E30 /* FindInPageIOSJSSupport */,
4B2754EB29E8C7DF00394032 /* Lottie */,
854007E62B57FC000001BD98 /* ZIPFoundation */,
);
productName = DuckDuckGo;
productReference = 84E341921E2F7EFB00BDBA6F /* DuckDuckGo.app */;
Expand Down Expand Up @@ -5991,6 +5997,7 @@
0202568C29881E4300E694E7 /* XCRemoteSwiftPackageReference "CocoaAsyncSocket" */,
0238E44D29C0FAA100615E30 /* XCRemoteSwiftPackageReference "ios-js-support" */,
4B2754EA29E8C7DF00394032 /* XCRemoteSwiftPackageReference "lottie-ios" */,
854007E52B57FB020001BD98 /* XCRemoteSwiftPackageReference "ZIPFoundation" */,
);
productRefGroup = 84E341931E2F7EFB00BDBA6F /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -6772,6 +6779,7 @@
85EE7F572246685B000FE757 /* WebContainerViewController.swift in Sources */,
1EC458462948932500CB2B13 /* UIHostingControllerExtension.swift in Sources */,
1E4DCF4E27B6A69600961E25 /* DownloadsListHostingController.swift in Sources */,
850F93DB2B594AB800823EEA /* ZippedPassKitPreviewHelper.swift in Sources */,
4BCD14672B05B682000B1E4C /* NetworkProtectionTermsAndConditionsStore.swift in Sources */,
020108A129A5610C00644F9D /* AppTPActivityHostingViewController.swift in Sources */,
C1F341C92A6926920032057B /* EmailAddressPromptViewController.swift in Sources */,
Expand Down Expand Up @@ -9913,6 +9921,14 @@
version = 3.3.0;
};
};
854007E52B57FB020001BD98 /* XCRemoteSwiftPackageReference "ZIPFoundation" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/weichsel/ZIPFoundation.git";
requirement = {
kind = exactVersion;
version = 0.9.17;
};
};
98A16C2928A11BDE00A6C003 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit";
Expand Down Expand Up @@ -10045,6 +10061,11 @@
package = 98A16C2928A11BDE00A6C003 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
productName = RemoteMessaging;
};
854007E62B57FC000001BD98 /* ZIPFoundation */ = {
isa = XCSwiftPackageProductDependency;
package = 854007E52B57FB020001BD98 /* XCRemoteSwiftPackageReference "ZIPFoundation" */;
productName = ZIPFoundation;
};
85875B6029912A9900115F05 /* SyncUI */ = {
isa = XCSwiftPackageProductDependency;
productName = SyncUI;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
{
"identity" : "trackerradarkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/TrackerRadarKit",
"location" : "https://github.com/duckduckgo/TrackerRadarKit.git",
"state" : {
"revision" : "a6b7ba151d9dc6684484f3785293875ec01cc1ff",
"version" : "1.2.2"
Expand All @@ -170,6 +170,15 @@
"revision" : "2d8172c11478ab11b0f5ad49bdb4f93f4b3d5e0d",
"version" : "1.1.1"
}
},
{
"identity" : "zipfoundation",
"kind" : "remoteSourceControl",
"location" : "https://github.com/weichsel/ZIPFoundation.git",
"state" : {
"revision" : "a3f5c2bae0f04b0bce9ef3c4ba6bd1031a0564c4",
"version" : "0.9.17"
}
}
],
"version" : 2
Expand Down
4 changes: 3 additions & 1 deletion DuckDuckGo/FilePreviewHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ struct FilePreviewHelper {
switch download.mimeType {
case .passbook:
return PassKitPreviewHelper(filePath, viewController: viewController)
case .multipass:
return ZippedPassKitPreviewHelper(filePath, viewController: viewController)
default:
return QuickLookPreviewHelper(filePath, viewController: viewController)
}
}

static func canAutoPreviewMIMEType(_ mimeType: MIMEType) -> Bool {
switch mimeType {
case .passbook:
case .passbook, .multipass:
return UIDevice.current.userInterfaceIdiom == .phone

case .reality, .usdz, .calendar:
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/MIMEType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Foundation

enum MIMEType: String {
case passbook = "application/vnd.apple.pkpass"
case multipass = "application/vnd.apple.pkpasses"
case usdz = "model/vnd.usdz+zip"
case reality = "model/vnd.reality"
case octetStream = "application/octet-stream"
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/PassKitPreviewHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class PassKitPreviewHelper: FilePreview {
viewController?.present(controller, animated: true)
}
} catch {
os_log("Can't present passkit: %s", type: .debug, error.localizedDescription)
os_log("Can't present passkit: %{public}s", type: .error, error.localizedDescription)
}
}
}
65 changes: 65 additions & 0 deletions DuckDuckGo/ZippedPassKitPreviewHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// ZippedPassKitPreviewHelper.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Common
import Foundation
import UIKit
import PassKit
import ZIPFoundation

class ZippedPassKitPreviewHelper: FilePreview {
private weak var viewController: UIViewController?
private let filePath: URL

required init(_ filePath: URL, viewController: UIViewController) {
self.filePath = filePath
self.viewController = viewController
}

func preview() {
do {
let passes: [PKPass] = try extractDataEntriesFromZipAtFilePath(self.filePath).compactMap({ try? PKPass(data: $0) })
if passes.count > 0,
let controller = PKAddPassesViewController(passes: passes) {
viewController?.present(controller, animated: true)
} else {
os_log("Can't present passkit: No valid passes in passes file", type: .error)
}
} catch {
os_log("Can't present passkit: %{public}s", type: .error, error.localizedDescription)
}
}

func extractDataEntriesFromZipAtFilePath(_ zipPath: URL) throws -> [Data] {
var dataObjects = [Data]()
let archive = try Archive(url: zipPath, accessMode: .read)
try archive.forEach { entry in
var passData = Data()
_ = try archive.extract(entry, skipCRC32: true) { data in
passData.append(data)
}

if passData.count > 0 {
dataObjects.append(passData)
}
}

return dataObjects
}
}

0 comments on commit f5401af

Please sign in to comment.