【问题标题】:ios: add printing, but keep compatibility with ios 3ios:添加打印,但保持与 ios 3 的兼容性
【发布时间】:2010-11-28 16:22:44
【问题描述】:

我正在尝试向 ios 应用程序添加打印功能。 虽然打印本身可以正常工作,并且该应用程序可以在 ios > 4 上运行,但我还没有弄清楚如何保持 ios 3.1 兼容性...

我猜问题是这样的:completionHandler:(UIPrintInteractionCompletionHandler)

你实现的 UIPrintInteractionCompletionHandler 类型的块来处理 打印作业的结束(例如,重置状态)和 处理打印中遇到的任何错误。

一旦我添加了块:

void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
};

该应用甚至无法在 iOS 3.1 上启动 可能是因为那里没有可用的块。

是的,我确保在 iOS 3.1 上启动时不会运行此代码...

if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.2) && ([UIPrintInteractionController isPrintingAvailable]))

所以我想知道是否有办法为 iOS >4.2 提供打印支持,但让它在 iOS 3.1 上运行?

也许有一种方法可以使用方法而不是“块”? 或者如何在受支持的 iOS 设备上进行打印并保持向后兼容 iOS 3.1 的正确方法是什么?

【问题讨论】:

  • 简短回答:不要使用 LLVM 编译器 1.6。 1) 您的项目的 Base SDK 必须是 iOS 4.2(或更高版本),2) 您的项目的部署目标必须是 iOS 3.1 或更高版本。 (所以你需要放弃 pre-3.1 iPhone 兼容性。),3)你项目的 C/C++ Compiler Version 必须是 LLVM GCC 4.2(如果你需要支持 pre-4.0 iOS)或 LLVM compiler 1.6(如果你只支持 iOS 4.0及以上,因为它不会弱链接支持块)。 ----/ 在 2010 年 11 月 22 日的帖子中找到了这个答案:marco.org

标签: iphone printing backwards-compatibility


【解决方案1】:

只需将 -weak_framework UIKit 添加到“其他链接器标志”下的项目设置中,并确保您使用条件代码来打印 API。 条件代码应该检查功能可用性,而不是操作系统版本:

    if (NSClassFromString(@"UIPrintInteractionController")){
    void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
    ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
    };
}

将您的项目目标设置为 iOS 3,一切顺利。

【讨论】:

  • 非常感谢!它当然可以通过构建配置来解决......我的问题是,我设置了 LLVM 编译器 1.6 [它不会对块进行弱链接支持]......它与 LLVM GCC 4.2 完美配合。另见:marco.org(2010 年 11 月 22 日输入)
  • 你仍然不能引用 UIPrint... 类,因为它们在 iOS 3.x 中不存在。你是怎么解决这个问题的?
  • objektivs,NSClassFromString 仅用于检测运行时是否支持 UIPrintInteractionController - 如果成功,您可以使用它,只需确保它在条件代码块内。
  • 旁注:“NSClassFromString”方法在某些情况下不起作用 - 当类存在但与记录的公共版本不同时。例如,UITapGestureRecognizer 存在于 OS 3.1.3 中,但直到 3.2 才记录和公开;在 3.1.3 崩溃时调用它(特别是访问 numberOfTapsRequired)。
  • 好的。所以你不必添加 -weak_framework UIKit 部分来让它工作。但是,“您项目的编译器必须是 LLVM-GCC 4.2 编译器或更新版本,或者 LLVM 编译器 (Clang) 1.5 或更新版本。”如此处所述:developer.apple.com/library/ios/#documentation/DeveloperTools/… 并注意它是 3.1 及更高版本(没有 3.0)。
【解决方案2】:

检测 AirPrint 是否可用的最佳做法是使用NSClassFromString。如果您通常使用此方法,那么您始终知道您想要的类是否可用,而无需硬编码哪些功能与哪个版本相对应。示例代码:

 Class printControllerClass = NSClassFromString(@"UIPrintInteractionController");
 if (printControllerClass) {
   [self setupCanPrintUI];
 } else {
   [self setupCannotPrintUI];
 }

这样您的应用仍然可以在以前的 iOS 版本上运行,但无法从它们打印。

我已经能够使用这种技术并在 iOS 3.0 设备上运行它,而块代码(基于 ^ 的东西)没有任何问题。在我的构建设置中,我将 Base SDK 设置为 iOS 4.2,并将部署目标设置为 iOS 3.0。

我在this blog post on printing in iOS 末尾发布了一个示例 Xcode 项目。这是一个在 iOS 3.0 设备和另一台 iOS 4.2 设备上成功运行的项目。您可能必须更改 info.plist 中的包标识符才能使代码签名为您工作,但这与打印内容无关。

【讨论】:

  • 我对“块代码”的问题是,我设置了 LLVM 编译器 1.6 [它不会对块进行弱链接支持]...它与 LLVM GCC 4.2 完美配合。阅读marco.org/1648550153(2010 年 11 月 22 日的条目)了解更多详情。
【解决方案3】:

在您的项目设置中将部署目标设置为 iOS 3.x。但是,将 Base SDK 设置为 4.2。现在您可以使用 4.2 类并且运行 3.x 的 iPhone 也可以安装您的应用程序。 请记住,当您在 iPhone 3.x 上使用 4.2 类时,应用程序会崩溃(因此请随时检查系统版本)。

【讨论】:

  • 我已经这样做了。问题是,带有completionHandler 的代码行将导致应用程序无法在iOS 3.1 上运行。但多亏了答案,我明白了原因。
【解决方案4】:
NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare:@"3.2" options: NSNumericSearch];
  if (order == NSOrderedSame || order == NSOrderedDescending && [[UIDevice currentDevice]isMultitaskingSupported]) {
   // >4.2
  }
               else {
                       //< 4.2
                }

注意: 还将 UIKit 框架设置从“必需”更改为“弱”,这将帮助您在 iOs = 4.2

上运行应用程序

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多