【问题标题】:How to retrieve a file/resource in a iOS framework bundle from a main program?如何从主程序中检索 iOS 框架包中的文件/资源​​?
【发布时间】:2023-03-10 01:18:01
【问题描述】:

我使用有关为 iOS 开发创建通用二进制框架的方法来分发库。我还想在框架中添加文件,并将它们加载到主程序中(实际上是一个 SSL 证书)。这与this StackOverflow question 有关,主要区别在于我想包含 XIB 以外的其他内容。

如果我们阅读与链接帖子相关的线程,似乎是不可能的。但是,提到了以下blog article;我们可以阅读:

“静态框架并不能完全替代标准框架 -- 访问框架资源的标准方法,例如+[NSBundle bundleForClass:] 将不会返回预期的包。捆绑路径是通过查询 dyld 的库路径来确定的 对应于符号地址——在静态链接的情况下, 这将返回静态库所在的二进制文件的路径 被链接了。此外,NSBundle/CFBundle 将检查以前的 堆栈 from 用于返回地址,并使用该返回地址 确定调用代码的 dyld 二进制路径。鉴于这些 限制,一些变通方法是可能的,例如使用-[NSBundle privateFrameworkPath] 定位到嵌入式框架的路径。”

我是 iOS 开发的初学者,我很难使用这种机制。使用privateFrameworksPath 确实会返回一个路径,但我不知道下一步该做什么来定位我要加载的文件。

是这样的:

NSBundle * bundle = [NSBundle bundleForClass:[self class]];
NSString * path = [bundle privateFrameworksPath]; // Works, return something like .../Frameworks
NSString * file = [path stringByAppendingPathComponent:@"MyFramework.framework/Versions/A/my-cert.der"]; 
NSData * trustedCertData = [NSData dataWithContentsOfFile:file]; // Returns nil

有什么想法吗?

【问题讨论】:

    标签: ios objective-c xcode


    【解决方案1】:

    以下代码在类似情况下对我有用

    NSBundle * bundle = [NSBundle bundleForClass:[self class]];
    NSString * file = [bundle pathForResource:@"my-cert" ofType:@"der"];; 
    NSData * trustedCertData = [NSData dataWithContentsOfFile:[file stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    

    NSBundle bundleForClass: 方法为当前类的框架返回一个包。因此,如果您从 MyFramework 中调用此方法,则无需再次使用 MyFramework.framework 附加路径,但如果这是您的问题,您会发现该调试。

    my-cert.der 中的破折号也可能需要替换为 % 等效项。因此stringByReplacingPercentEscapesUsingEncoding: 调用。

    【讨论】:

      【解决方案2】:

      访问框架包

      关键是传递属于框架的类的任何metatype[About]

      //Objective-C
      NSBundle *someBundle = [NSBundle bundleForClass:[SomeFrameworkClass class]];
      
      //Swift
      
      //via public framework's class
      let frameworkBundle = Bundle(for: SomeFrameworkClass.self)
      //or via Bundle Identifier(PRODUCT_BUNDLE_IDENTIFIER)
      let frameworkBundle = Bundle(identifier: "com.someid") 
      //or if it is called from the framework
      let frameworkBundle = Bundle(for: type(of: self))
      let frameworkBundle = Bundle(for: Self.self)
      
      //working with bundle as usual
      

      [Vocabulary]

      【讨论】:

        猜你喜欢
        • 2018-06-19
        • 1970-01-01
        • 1970-01-01
        • 2015-04-30
        • 1970-01-01
        • 2016-07-24
        • 1970-01-01
        • 2011-11-05
        • 2010-11-13
        相关资源
        最近更新 更多