-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[file_selector] Convert iOS to Swift and SPM (#6755)
Converts the plugin and its tests to Swift, and re-adds the SPM support that was reverted due to modulemap issues. In order to avoid the ugliness and loss of type saftey of using associated objects in the Swift version, this replaces that with a bridge object that serves as a delegate instead of the plugin, and manages its own lifetime in coordination with the plugin. While this is one PR, the conversion was done in individual steps, each of which is a commit: - Rewrite just the tests in Swift, with no implementation changes, ensuring that everything still passed. - Rewrite the implementation in Swift, changing the tests only as necessary for the structural changes to the implementation due to the removal of associated objects - Re-add SPM The changes in the generated Dart files are just due to updating to the latest version of Pigeon (to avoid writing the Swift implementation against an older version of the Swift API, and then having to update again later for breaking changes). Part of flutter/flutter#119015 Fixes flutter/flutter#146903
- Loading branch information
1 parent
66530f2
commit df16d4e
Showing
24 changed files
with
487 additions
and
474 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 0 additions & 84 deletions
84
packages/file_selector/file_selector_ios/example/ios/RunnerTests/FileSelectorTests.m
This file was deleted.
Oops, something went wrong.
85 changes: 85 additions & 0 deletions
85
packages/file_selector/file_selector_ios/example/ios/RunnerTests/FileSelectorTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import XCTest | ||
|
||
@testable import file_selector_ios | ||
|
||
final class TestViewPresenter: ViewPresenter { | ||
public var presentedController: UIViewController? | ||
|
||
func present( | ||
_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)? = nil | ||
) { | ||
presentedController = viewControllerToPresent | ||
} | ||
} | ||
|
||
class FileSelectorTests: XCTestCase { | ||
func testPickerPresents() throws { | ||
let plugin = FileSelectorPlugin() | ||
let picker = UIDocumentPickerViewController(documentTypes: [], in: UIDocumentPickerMode.import) | ||
let presenter = TestViewPresenter() | ||
plugin.documentPickerViewControllerOverride = picker | ||
plugin.viewPresenterOverride = presenter | ||
|
||
plugin.openFile( | ||
config: FileSelectorConfig(utis: [], allowMultiSelection: false) | ||
) { _ in } | ||
|
||
XCTAssertEqual(plugin.pendingCompletions.count, 1) | ||
XCTAssertTrue(picker.delegate === plugin.pendingCompletions.first) | ||
XCTAssertTrue(presenter.presentedController === picker) | ||
} | ||
|
||
func testReturnsPickedFiles() throws { | ||
let plugin = FileSelectorPlugin() | ||
let picker = UIDocumentPickerViewController(documentTypes: [], in: UIDocumentPickerMode.import) | ||
plugin.documentPickerViewControllerOverride = picker | ||
plugin.viewPresenterOverride = TestViewPresenter() | ||
let completionWasCalled = expectation(description: "completion") | ||
|
||
plugin.openFile( | ||
config: FileSelectorConfig(utis: [], allowMultiSelection: false) | ||
) { result in | ||
switch result { | ||
case .success(let paths): | ||
XCTAssertEqual(paths, ["/file1.txt", "/file2.txt"]) | ||
case .failure(let error): | ||
XCTFail("\(error)") | ||
} | ||
completionWasCalled.fulfill() | ||
} | ||
plugin.pendingCompletions.first!.documentPicker( | ||
picker, | ||
didPickDocumentsAt: [URL(string: "file:///file1.txt")!, URL(string: "file:///file2.txt")!]) | ||
|
||
waitForExpectations(timeout: 30.0) | ||
XCTAssertTrue(plugin.pendingCompletions.isEmpty) | ||
} | ||
|
||
func testCancellingPickerReturnsEmptyList() throws { | ||
let plugin = FileSelectorPlugin() | ||
let picker = UIDocumentPickerViewController(documentTypes: [], in: UIDocumentPickerMode.import) | ||
plugin.documentPickerViewControllerOverride = picker | ||
plugin.viewPresenterOverride = TestViewPresenter() | ||
let completionWasCalled = expectation(description: "completion") | ||
|
||
plugin.openFile( | ||
config: FileSelectorConfig(utis: [], allowMultiSelection: false) | ||
) { result in | ||
switch result { | ||
case .success(let paths): | ||
XCTAssertEqual(paths.count, 0) | ||
case .failure(let error): | ||
XCTFail("\(error)") | ||
} | ||
completionWasCalled.fulfill() | ||
} | ||
plugin.pendingCompletions.first!.documentPickerWasCancelled(picker) | ||
|
||
waitForExpectations(timeout: 30.0) | ||
XCTAssertTrue(plugin.pendingCompletions.isEmpty) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,11 +13,14 @@ Displays the native iOS document picker. | |
s.license = { :type => 'BSD', :file => '../LICENSE' } | ||
s.author = { 'Flutter Dev Team' => '[email protected]' } | ||
s.source = { :http => 'https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_ios' } | ||
s.source_files = 'file_selector_ios/Sources/file_selector_ios/**/*.{h,m}' | ||
s.module_map = 'file_selector_ios/Sources/file_selector_ios/include/cocoapods_file_selector_ios.modulemap' | ||
s.source_files = 'file_selector_ios/Sources/file_selector_ios/**/*.swift' | ||
s.dependency 'Flutter' | ||
s.platform = :ios, '12.0' | ||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } | ||
s.swift_version = '5.0' | ||
s.xcconfig = { | ||
'LIBRARY_SEARCH_PATHS' => '$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)/ $(SDKROOT)/usr/lib/swift', | ||
'LD_RUNPATH_SEARCH_PATHS' => '/usr/lib/swift', | ||
} | ||
s.resource_bundles = {'file_selector_ios_privacy' => ['file_selector_ios/Sources/file_selector_ios/Resources/PrivacyInfo.xcprivacy']} | ||
end |
31 changes: 31 additions & 0 deletions
31
packages/file_selector/file_selector_ios/ios/file_selector_ios/Package.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// swift-tools-version: 5.9 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "file_selector_ios", | ||
platforms: [ | ||
.iOS("12.0") | ||
], | ||
products: [ | ||
.library(name: "file-selector-ios", targets: ["file_selector_ios"]) | ||
], | ||
dependencies: [], | ||
targets: [ | ||
.target( | ||
name: "file_selector_ios", | ||
dependencies: [], | ||
resources: [ | ||
.process("Resources") | ||
], | ||
cSettings: [ | ||
.headerSearchPath("include/file_selector_ios") | ||
] | ||
) | ||
] | ||
) |
Oops, something went wrong.