尽管“hasStrings”为真,但 UIPasteBoard“string”属性返回 nil

Posted

技术标签:

【中文标题】尽管“hasStrings”为真,但 UIPasteBoard“string”属性返回 nil【英文标题】:UIPasteBoard "string" property returning nil despite "hasStrings" being true 【发布时间】:2021-02-04 01:55:20 【问题描述】:

我有以下代码用于抓取用户从应用程序外部复制到剪贴板的文本,以便他们可以将其粘贴到应用程序中:

UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];

if ([pasteboard hasStrings])

    NSString *text = pasteboard.string;

这一直很好,直到ios14 我注意到我一直在崩溃,因为pasteboard.stringnil,尽管hasStrings 是真的。

我查看了文档,发现确实有可能pasteboard.stringnil

此属性中存储的值是一个 NSString 对象。这 相关的表示类型数组是 UIPasteboardTypeListString,其中包括类型 kUTTypeUTF8PlainText。 设置此属性将替换粘贴板中的所有当前项目 与新项目。如果第一项没有指定的值 类型,返回 nil。

我的意思是剪贴板中存在某种不是kUTTypeUTF8PlainText 的字符串,这就是为什么pasteboard.stringnil,但这是正确的解释吗?

我只是对这里到底发生了什么感到困惑,如果我遇到pasteboard.stringnil 的情况,我不确定要告诉我的用户什么?

【问题讨论】:

【参考方案1】:

-[UIPasteboard hasStrings] == YES 仅表示粘贴板中的项目的类型为 public.utf8-plain-text 或任何其他表明它是字符串的类型。

但是,如果 NSString 类的对象不能从 itemProviders 提供的任何数据中构造出来,-[UIPasteboard string] 仍然可以返回 nil

这是一个重现您所处情况的示例:

首先实现一个符合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

然后将测试对象放入pastboard

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;
    

【讨论】:

以上是关于尽管“hasStrings”为真,但 UIPasteBoard“string”属性返回 nil的主要内容,如果未能解决你的问题,请参考以下文章

警告:tensorflow:忽略带有图像 id 的检测,尽管配置参数为真

尽管快照中有数据,Streambuilder snapshot.hasData 永远不会为真

当 RTL 为真时,ExtJS 5 工具栏按钮不会右对齐

如果另一个互斥参数为真,则将默认值设置为假

perl 中有“0 但为真”,但是不是有“42 但为假”?

为啥 (new Date() == new Date()) 为假,但 (Date() == Date()) 为真? [复制]