Swift 패키지 관리자: 리소스를 Swift 패키지와 함께 번들

13592 단어 swiftios
최근에 ID3TagEditor swift 패키지를 최신 swift tools 버전(5.3)으로 업그레이드했습니다.업그레이드 과정에서, 나는 지금 네가 Swift 패키지로 Reources를 묶을 수 있다는 것을 발견했다.이 문서에서는 Swift 패키지와 Xcode의 표준 항목으로 프로젝트를 구축할 수 있는 흥미로운 팁을 제공합니다.
지난 몇 주 동안 나는 또 나의 ID3TagEditor 도서관에서 일하기 시작했다.새로운 재미있는 기능 (노선도를 보시겠습니까? 검사 kanban board 또는 milestones 을 추가하기 전에, 새 Xcode 12에서 발표한 최신 구축 도구를 일반적인 업그레이드했습니다.이 릴리즈(Swift tools 5.3 Edition)에 포함된 새로운 흥미로운 기능은 리소스를 Swift 패키지와 함께 번들로 묶을 수 있다는 것입니다.이번 발표에 앞서 자원을 Swift 패키지로 포장하려면 이상한 기술과 해커 공격을 사용해야 합니다.따라서 ID3TagEditor 라이브러리의 예를 들어 번들 리소스에 대한 지원을 추가하는 방법을 살펴보겠습니다.
구체적으로 말하면, 저는 귀하께 검수 테스트를 포함한 모든 테스트 세트를 어떻게 실행하는지 보여 드리겠습니다. 이 테스트들은 mp3와 이미지 자원을 사용하여 ID3TagEditor가 추가한 ID3 태그의 정확성을 검사합니다.

구현


자원 묶음을 지원하기 위해서는 패키지를 구축하는 데 사용되는 swift 도구를 업그레이드해야 합니다.이렇게 하려면 상단의 주석을 변경하기만 하면 된다.
// swift-tools-version:5.3

//...other code
내 ID3TagEditor 중, 나는 몇몇 검수 테스트를 하고, 일부 mp3 파일과 그림을 사용하여 ID3TagEditor가 예상대로 작동하는지 검사한다.Swift tools 5.3 이전에 Linux 플랫폼에서 이 테스트들을 사용하지 않았습니다. (이 플랫폼은 SwiftPM 귀속 라이브러리만 지원합니다.)현재 자원을 불러올 수 있는 새로운 Swift 패키지 Package.swifttargets(...) 함수 매개 변수 testTargets(...) 가 있습니다.resources 매개 변수는 자원 프로세스 규칙 목록을 입력값으로 한다.두 가지 규칙 중 하나를 선택할 수 있습니다.
  • 프로세스 규칙.resources 함수를 사용하여 이 규칙을 만들 수 있습니다. (공식 문서 here 를 찾을 수 있습니다.이 규칙은 패키지를 구축하는 플랫폼에 따라 자원을 처리할 수 있도록 합니다.이것은 기본적으로 구축 도구가 유형과 플랫폼에 따라 일부 파일을 최적화한다는 것을 의미한다(예를 들어 목표 플랫폼이 iOS라면 이미지가 최적화될 것이다).지역/언어에 따라 다양한 규칙을 지원할 수도 있습니다.
  • 복제 규칙.static func process(_ path: String, localization: Resource.Localization? = nil) -> Resource 함수를 사용하여 이 규칙을 만들 수 있습니다. (공식 문서 here 를 찾을 수 있습니다.이 규칙은 최적화가 없기 때문에 자원을 묶는 것을 허용한다.
  • 상술한 두 규칙 함수는 모두 static func copy(_ path: String) -> Resource 매개 변수를 받아들인다.이 가능하다, ~할 수 있다,...
  • 특정 파일의 경로
  • 특정 폴더의 경로
  • 이 모든 정보를 고려하여, 나는 이 자원을 나의 테스트 목표에 추가하고, SwiftPM을 위해 검수 테스트를 사용하려고 한다. (그래서 지금도 Linux에서 사용할 수 있다)☺️). 따라서 ID3TagEditor의 _ path: String 호출에 resources 매개변수를 추가합니다.입력 값은 하나의 그룹입니다. 하나의 규칙만 있습니다. testTarget 폴더를 매개 변수로 하는 process 규칙입니다. 저는 ID3TagEditor 검수 테스트에 사용되는 모든 자원 (mp3와 이미지) 을 가지고 있습니다.다음은 완전한 Examples 파일입니다.
    // swift-tools-version:5.3
    
    import PackageDescription
    
    let package = Package(
        name: "ID3TagEditor",
        products: [
            .library(
                name: "ID3TagEditor",
                targets: ["ID3TagEditor"]
            )
        ],
        dependencies: [],
        targets: [
            .target(
                name: "ID3TagEditor",
                dependencies: [],
                path: "./Source",
                exclude: ["Info.plist"]
            ),
            .testTarget(
                name: "ID3TagEditorTests",
                dependencies: ["ID3TagEditor"],
                path: "./Tests",
                exclude: ["Utils/PathLoaderXcodeProj.swift", "Info.plist"],
                resources: [.process("Examples")]
            )
        ],
        swiftLanguageVersions: [.v5]
    )
    
    현재 문제는 대상과 묶인 자원을 어떻게 사용하거나 불러옵니까?Swift 패키지를 구축하면 빌드 도구가 자동으로 Packages.swift 파일을 생성합니다.이 파일은 소스 코드를 구축하는 환경을 기반으로 하는 패키지의 사용 가능한 번들을 포함하는 새로운 resource_bundle_accessor 속성을 공개합니다.
  • 응용 프로그램에 연결할 때 패키지를 생성하면Bundle.module Bundle.module
  • 프레임에 연결할 때 패키지를 구축하면Bundle.main.resourceURL Bundle.module
  • 명령줄에서 패키지를 생성하면 Bundle(for: BundleFinder.self).resourceURL 포함 Bundle.module
  • import class Foundation.Bundle
    
    private class BundleFinder {}
    
    extension Foundation.Bundle {
        /// Returns the resource bundle associated with the current Swift module.
        static var module: Bundle = {
            let bundleName = "ID3TagEditor_ID3TagEditorTests"
    
            let candidates = [
                // Bundle should be present here when the package is linked into an App.
                Bundle.main.resourceURL,
    
                // Bundle should be present here when the package is linked into a framework.
                Bundle(for: BundleFinder.self).resourceURL,
    
                // For command-line tools.
                Bundle.main.bundleURL,
            ]
    
            for candidate in candidates {
                let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
                if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
                    return bundle
                }
            }
            fatalError("unable to find bundle named ID3TagEditor_ID3TagEditorTests")
        }()
    }
    
    따라서 ID3TagEditor의 경우 Xcode에서 Swift 패키지를 열고 구축하거나 명령줄에서 구축할 때Bundle.main.bundleURL에 올바른 패키지가 포함됩니다.따라서 ID3TagEditor 테스트 대상에 바인딩된 리소스의 경로를 가져오고Bundle.module 테스트에서 로드/사용할 수 있습니다.사실상, 나는 Bundle.module.path(forResource: <resource name>, ofType: <file type>) 클래스를 만들었는데, 나는 검수 테스트에서 그것을 사용하여 테스트 자원을 불러왔다.
    import Foundation
    
    class PathLoader {
        func pathFor(name: String, fileType: String) -> String {
            return Bundle.module.path(forResource: name, ofType: fileType)!
        }
    }
    
    Xcode에서 Swift 패키지로 ID3TageEditor를 연 후 테스트의 성공적인 실행을 보여 주는 화면 캡처를 찾을 수 있습니다.

    이 설정에는 또 문제가 하나 있다.ID3TagEditor도 Xcode 작업공간으로 구성되어 있습니다. 저장소에 관련 프레젠테이션 응용 프로그램이 포함되어 있기 때문에 라이브러리를 개발할 때 관리하는 방법이 필요합니다.워크스페이스 보기에서 ID3TageEditor를 구축하려고 하면 컴파일되지 않습니다.왜?PathLoader 파일 (위에서 보여준 것) 은 자동으로 생성되지 않기 때문에, swift 패키지를 작업 영역으로 구축하는 프로젝트이고, 위에서 보여준 resource_bundle_accessor 클래스에 오류가 포함되어 있습니다 PathLoader.제가 뭘 할 수 있을까요?나는 단지 Type 'Bundle' has no member 'module' 클래스의 새로운 버전을 만들었을 뿐이다. PathLoader 구조 함수를 사용하여 패키지를 정확하게 얻었을 뿐이다. 그 중에서 Bundle(for: type(of: self))는 호출self의 테스트 클래스이다.그리고 SwiftPM 구축 도구PathLoader가 구현한 파일에서 테스트 목표를 삭제하고 새로운 구현만 추가하여 PathLoader라는 단독 파일에 넣었습니다.반대로 위PathLoaderXcodeProj.swift에서 테스트 목표에서 Xcode 사용을 배제한 것을 보실 수 있습니다Packagkage.swift.이런 방식을 통해 나는 모든 테스트를 오류 없이 실행할 수 있다.다음은 내가 방금 너에게 설명한 설정 캡처를 찾을 수 있다.


    결론


    SwiftPM 및 번들 리소스에 대한 자세한 내용은 official Apple documentation에서 확인할 수 있습니다.보시다시피 애플은 도구 생태계 구축을 개선하고 개발자들의 생활을 가볍게 하기 위해 대량의 자원을 투입하고 있다.비록 나는 여전히 hope that Apple will finally fully embrace PWA(이렇게 많은 쓸모없고 인터넷 응용 프로그램일 수 있는 쓰레기 응용 프로그램은 모두 사라질 수 있다)😏), 개발자(개발자)가 진정으로 유용한 로컬 응용 프로그램을 개발하고 있는 것을 보니 매우 기쁘다.😁) 새로운 툴을 사용하여 애플리케이션 구축😍.
    애초 2020년 10월 19일https://www.fabrizioduroni.it에 발표됐다.

    좋은 웹페이지 즐겨찾기