【问题标题】:UIPasteBoard "string" property returning nil despite "hasStrings" being true尽管“hasStrings”为真,但 UIPasteBoard“string”属性返回 nil
【发布时间】: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 的情况,我不确定要告诉我的用户什么?

【问题讨论】:

    标签: ios objective-c ios14 uipasteboard


    【解决方案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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多