问题描述
我有以下代码用于抓取用户从应用程序外部复制到剪贴板的文本,以便他们可以将其粘贴到应用程序中:
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
if ([pasteboard hasstrings])
{
Nsstring *text = pasteboard.string;
}
这一直很有效,直到 iOS14
我注意到我一直在崩溃,因为 pasteboard.string
是 nil
,尽管 hasstrings
是真的。
我查看了文档,发现确实,pasteboard.string
可能是 nil
:
存储在这个属性中的值是一个 Nsstring 对象。这 表示类型的关联数组是 UIPasteboardTypeListString,包括类型 kUTTypeUTF8PlainText。 设置此属性会替换粘贴板中的所有当前项目 与新项目。如果第一项没有指定的值 类型,返回 nil。
我的意思是剪贴板中有某种不是 kUTTypeUTF8PlainText
的字符串,这就是为什么 pasteboard.string
是 nil
,但这是正确的解释吗?
我只是对这里到底发生了什么感到困惑,如果遇到 pasteboard.string
是 nil
的情况,我不确定要告诉我的用户什么?
解决方法
-[UIPasteboard hasStrings] == YES
仅表示粘贴板中的项目具有 public.utf8-plain-text
类型或任何其他表明它是字符串的类型。
但是,如果 -[UIPasteboard string]
类的对象不能从 nil
提供的任何数据构造出来,NSString
仍然可以返回 itemProviders
。
以下是重现您所处情况的示例:
首先实现一个符合NSItemProviderWriting
的测试类
#import <Foundation/Foundation.h>
static NSString *const UTTypeUTF8PlainText = @"public.utf8-plain-text";
@interface TestObject : NSObject <NSItemProviderWriting>
@end
@implementation TestObject
- (NSData *)randomDataWithLength:(NSUInteger)length {
NSMutableData *data = [NSMutableData dataWithLength:length];
SecRandomCopyBytes(kSecRandomDefault,length,data.mutableBytes);
return data;
}
#pragma mark - NSItemProviderWriting
+ (NSArray<NSString *> *)writableTypeIdentifiersForItemProvider {
return @[UTTypeUTF8PlainText];
}
- (nullable NSProgress *)loadDataWithTypeIdentifier:(nonnull NSString *)typeIdentifier forItemProviderCompletionHandler:(nonnull void (^)(NSData * _Nullable,NSError * _Nullable))completionHandler {
// random data that an utf8 string may not be constructed from
NSData *randomData = [self randomDataWithLength:1];
completionHandler(randomData,nil);
return nil;
}
@end
然后将测试对象放入粘贴板
if (@available(iOS 11.0,*)) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
TestObject *item = [TestObject new];
[pasteboard setObjects:@[item]];
if ([pasteboard hasStrings]) {
// text may be nil
NSString *text = pasteboard.string;
}
}