我有一个带有“共享”按钮的应用程序。我想根据活动类型自定义共享哪些内容。例如,消息可能会获取图像和文本,而AirDrop只会获取文件。
我实际上可以完美地工作,并且我使用的代码在iOS 10和iOS 10的每个版本中都能正常工作。但是我意识到我在不应该返回的位置返回了nil,所以我试图找出解决方法。
我做这样的事情来设置我的活动视图控制器:
JUNActivityProvider *fileProvider = [[JUNActivityProvider alloc] initWithPlaceholderItem:[NSObject new]];
fileProvider.objectID = objectID;
fileProvider.fileURL = fileURL;
JUNActivityProvider *textProvider = [[JUNActivityProvider alloc] initWithPlaceholderItem:[NSString new]];
textProvider.objectID = objectID;
...
UIActivityViewController *activityController = [[UIActivityViewController alloc]
initWithActivityItems:@[fileProvider,imageProvider,textProvider,urlProvider,printFormatter]
applicationActivities:nil];
然后在中JUNActivityProvider
,我有一个item
基于的自定义返回值的方法activityType
:
- (id)item {
if (self.fileURL) {
if ([self.activityType isEqualToString:UIActivityTypeAirDrop]) {
// Create the file
return url;
}
} else if ([self.placeholderItem isKindOfClass:[UIImage class]]) {
if ([self.activityType isEqualToString:UIActivityTypeAirDrop] == NO &&
[self.activityType isEqualToString:UIActivityTypeMail] == NO &&
[self.activityType isEqualToString:UIActivityTypePrint] == NO) {
// Create the image
return image;
}
} else if ([self.placeholderItem isKindOfClass:[NSString class]]) {
if ([self.activityType isEqualToString:UIActivityTypeMail]) {
return @"example one";
} else if ([self.activityType isEqualToString:UIActivityTypeMessage] ||
[self.activityType isEqualToString:UIActivityTypeCopyToPasteboard]) {
return @"example two";
}
}
return nil;
}
return nil
最后的回报就是问题所在。它可以正常工作,并且完全符合我的要求,当没有共享该项目时,它几乎为零。书面文档没有说必须返回一个值,但是头文件可以:
- (nonnull id)item;
//当用户选择活动时在辅助线程上调用。您必须继承并返回非nil值。
我不想在期望非空值时返回nil来冒着崩溃的风险,因此我需要解决此问题。据我所知,我唯一的选择是停止使用UIActivityItemProvider
,而是UIActivityItemSource
自己实现该协议。该协议包括方法activityViewController:itemForActivityType:
,该方法明确指出您可以在此处返回nil:
如果为一个活动类型注册了多个项目,则为零,只要其中一个项目返回实际值即可。
完美的。但这是问题所在:activityViewController:itemForActivityType:
在主线程上被调用,这尤其导致我的其中一个项目出现了问题。这是正在发生的事情的摘要:
activityViewController:itemForActivityType:
在主线程上被调用,因此它在工作时会锁定。我不知道如何处理这个问题。基本上,我需要防止方法返回直到准备好为止,但是由于需要在那里做一些工作,所以无法锁定主线程。看来...不可能吗?有什么办法可以使这项工作吗?
提出增强请求后,我即将放弃并选择归还nil
或退还[NSNull null]
。但是后来我意识到绝对可以解决这个问题。
尽管UIActivityItemProvider包括其自身的功能,但它仍然非常实现UIActivityItemSource协议。我知道。我没有考虑的是,这意味着我可以覆盖activityViewController:itemForActivityType:
并在适当的时候返回nil
那里。
所以我的item
方法的最后一行现在看起来像这样:
return self.placeholderItem;
您也可以返回[NSNull null]
此处,或者实际上返回任何对象。我选择了placeholderItem,因为它看起来更安全-至少,我知道它会返回预期类型的对象,以防实现方面的任何变化。
然后,所有我需要做的就是添加自己的实现activityViewController:itemForActivityType:
(我们是允许返回nil):
- (nullable id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(UIActivityType)activityType {
id item = [super activityViewController:activityViewController itemForActivityType:activityType];
if ([item isEqual:self.placeholderItem]) return nil;
return item;
}
只需调用super即可获得该项目,如果您不想包含该项目,则返回nil,否则返回该项目。请注意,如果你placeholderItem
要永远等于你真正的东西也想分享,您需要更改这个实现的位,但相同的基本概念应该工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句