编写兼容iOS 6的基础SDK的iOS7代码

8
我们现在正在销售一款iOS应用,同时使用相同的代码库在XCode 5 DP上开发iOS 7版本。
我们真的需要为现有的iOS 5/6客户立即发布更新,但是当我们将项目重新加载到XCode 4中时,它会因为不存在的属性而报错,因为基本SDK变成了iOS 6,而不是7。
// Only run this bit on iOS 7
if ([self respondsToSelector:@selector(setFooForExtendedLayout:)])
{
    self.fooForExtendedLayout = UIFooEdgeLeft | UIFooEdgeRight;
}

float bottomOffset = 0;
// Only run this bit on iOS 7, else leave bottomOffset as 0
if ([self.hostController respondsToSelector:@selector(bottomLayoutFoo)])
    bottomOffset = self.hostController.bottomLayoutFoo.length;

(obfuscated to avoid breaking NDA)
XCode错误:
• 在“UIViewController *”对象上找不到属性'fooForExtendedLayout' • 使用未声明的标识符“UIFooEdgeLeft” • 使用未声明的标识符“UIFooEdgeRight” • 在“UIViewController *”对象上找不到属性'bottomLayoutFoo'
注释掉新代码将很痛苦。重写代码以兼容旧版和新版基础SDK的正确方法是什么?现在(通过XCode 4并构建iOS 6 SDK)提交它是否会冒任何应用商店拒绝的风险?
5个回答

7
我建议等到iOS 7准备好后再提交您的更新。
然而,有方法可以解决这个问题。
引用:

在类型为“UIViewController *”的对象上找不到属性“fooForExtendedLayout”

由于属性只是语法糖,因此修复此类错误的简单方法是使用选择器调用方法(setter):
[ self performSelector: NSSelectorFromString( "setFooForExtendedLayout:" ) withObject: ( id )xxx ];
@selector() 不能使用,因为你正在使用 iOS 6 SDK 而要求 iOS 7 选择器。
因此需要使用 NSSelectorFromString
withObject 参数是用于对象的,正如其名称所示。但是由于对象是指针,并且您的方法采用枚举值,因此您实际上可以使用强制转换来传递它而没有问题。

使用未声明的标识符 'UIFooEdgeLeft'
使用未声明的标识符 'UIFooEdgeRight'

关于您的枚举值,现在没有这样的技巧。
唯一的方法是声明它们,并使用与 iOS 7 SDK 中相同的值,祈祷它不会在正式发布之前更改
所以现在取决于你...个人而言,我会等待。

这正是我一直在寻找的,谢谢。也感谢您回答了问题的另一部分,即分享您对此的保留意见。 - Carlos P

7
这是在iOS 6和7 SDK上都能编译的代码的推荐方式
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
    if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
        self.edgesForExtendedLayout = UIRectEdgeLeft | UIRectEdgeRight;
#endif

5

您可以使用以下方法:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
{
    self.edgesForExtendedLayout = UIRectEdgeNone;
}
#endif

1
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO 是什么/在哪里? - daihovey
这是一个宏定义:#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) - Alena

1
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
{
    self.edgesForExtendedLayout = UIRectEdgeNone;
}
#endif

-2

编辑:此答案(以及问题)已不再相关,因为现在已发布了Xcode 5!请在投票时考虑这一点;)

使用SCM工具获取两个不同的代码分支的原因是由于在切换具有相同Xcode项目和相同代码和资源基础的Xcode Developer Preview版本和Xcode Release版本时可能会出现微妙的问题。项目文件和故事板或xib可能会在幕后更改,并且可能会损坏。这不是因为没有办法在代码中找到解决方案!尽管如此,我不建议在相同的Xcode项目上使用不同的Xcode版本。这可能会让你头疼!


正确的方法是使用源代码管理工具,如git。您应该拥有一个“iOS 6”分支,用于维护发布版本,并且您应该拥有一个或多个开发分支,在其中使用Xcode和iOS的预发布版本。


我理解你的观点,但问题是如何重新编写所发布的代码,以便它可以针对两个SDK进行编译。 - Carlos P
使用一些奇怪的解决方法来解决一个可以轻松避免的问题是否更好? - CouchDeveloper
我知道,我知道……这是个好问题,而且我倾向于同意你的看法。然而,这不是这个问题。 - Carlos P
在使用Xcode 4.x/当前基础SDK和Xcode beta版本预发布基础SDK开发同一 Xcode项目时,可能会遇到许多问题。请注意,Xcode 4.x 可能无法打开由DP版本修改的项目,或者IB在打开xib文件时会出现问题。还可能由资源和其他支持文件的beta版本创建细微问题。如果您还没有这样做,请利用git来获得优势。它是一个很棒的工具 - 正是您所需要的。 ;) - CouchDeveloper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接