У меня есть приложение с кнопкой Share. Я хочу настроить общий контент, основанный на типе активности. Например, сообщения могут получить изображение и текст, тогда как AirDrop просто получит файл.Как я могу изменить элементы, используемые UIActivityViewController в этом сценарии?
У меня на самом деле это прекрасно работает, и код, который я использую, отлично работает в каждой версии iOS через iOS 10. Но я понял, что возвращаю ноль, где я не должен, поэтому я Я пытаюсь понять, как это исправить.
я сделать что-то вроде этого, чтобы настроить мой контроллер вид деятельности:
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;
// вызывается на вторичном потоке, когда пользователь выбирает активность. вы должны подклассифицировать и вернуть значение, отличное от нуля.
Я не хочу рисковать сбоем, возвращая нуль, когда ожидается ненулевое значение, поэтому мне нужно исправить это. Насколько я могу судить, мой единственный вариант - прекратить использование UIActivityItemProvider
и вместо этого реализовать протокол UIActivityItemSource
самостоятельно. Этот протокол включает в себя метод activityViewController:itemForActivityType:
, в котором четко говорится, что вы можешь возврат ноля есть:
Может быть ноль, если несколько элементов были зарегистрированы для одного вида деятельности, так долго, как один из элементов возвращает фактическое значение ,
Perfect. Но вот проблема: activityViewController:itemForActivityType:
вызывается в основном потоке, что вызывает проблемы с одним из моих элементов в частности. Вот краткое изложение того, что происходит:
- Мне нужно вызвать некоторые методы, которые выполняются асинхронно. Чтобы справиться с этим, я попытался использовать семафор отправки. Это препятствует возврату метода, пока у меня не будет возможности установить возвращаемое значение.
- С
activityViewController:itemForActivityType:
вызывается в основном потоке, который блокируется во время работы. - Мне нужно нарисовать UIView в изображение. Если я попытаюсь выполнить эту работу в основном потоке, ничего не произойдет до тех пор, пока семафор не истечет. Но если я не делаю этого в основном потоке, он падает.
Я в затруднении, как бороться с этим. В основном мне нужно, чтобы метод возвращался, пока я не готов, но я не могу заблокировать основной поток, так как мне нужно сделать там какую-то работу. Это кажется ... невозможно? Есть ли способ сделать эту работу?
Вы пытались вернуть '[NSNull null]' из вашей предыдущей попытки (UIActivityItemProvider)? Это возвращаемое значение «non-nil» в том смысле, что оно является объектом, но часто используется в API Cocoa для обозначения нулевого/пустого результата (и у меня был успех с этим в других местах с помощью UIActivityItemSource. – tgaul
@tgaul : Использование '[NSNull null]' "работает" в том, что оно удовлетворяет требованию 'nonnull' и не * кажется * вызывать какие-либо проблемы, но это делает меня очень нервным - я не могу понять, что он делает с этим Я немного склонен просто придерживаться 'nil' только потому, что это не вызвало каких-либо заметных проблем в течение многих лет. – robotspacer
Я подал сообщение об ошибке, предполагающее, что свойство' item' должно быть равно null: http://www.openradar.me/radar?id=4563896690016256 или rdar: // 28394697 – robotspacer