静态快速​​操作在目标 c iOS 中不起作用

Posted

技术标签:

【中文标题】静态快速​​操作在目标 c iOS 中不起作用【英文标题】:Static Quick Actions not working in objective c iOS 【发布时间】:2020-11-11 19:02:17 【问题描述】:

我对 ios 应用程序开发非常陌生,我一直在学习教程来建立我的职业生涯。因此,从我开始尝试根据客户项目在 Objective C 中实现静态快速操作。我能够在按下图标时添加键并获得选项。但是当我按下快速操作时,什么也没有发生,它只是启动应用程序。我研究了很多,我尝试过,但徒劳无功。下面是我写的 Appdelegate 代码:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    // Override point for customization after application launch.
    BOOL shouldPerformAdditionalDelegateHandling = YES;
    
    
    // Check API availiability
    // UIApplicationShortcutItem is available in iOS 9 or later.
    if([[UIApplicationShortcutItem class] respondsToSelector:@selector(new)])
        NSLog(@"HERE");
        //  [self configDynamicShortcutItems];
        
        // If a shortcut was launched, display its information and take the appropriate action
        UIApplicationShortcutItem *shortcutItem = [launchOptions objectForKeyedSubscript:UIApplicationLaunchOptionsShortcutItemKey];
        
        if(shortcutItem)
        
            NSLog(@"shortcut launch");
            // When the app launch at first time, this block can not called.
            
            [self handleShortCutItem:shortcutItem];
            
            // This will block "performActionForShortcutItem:completionHandler" from being called.
            shouldPerformAdditionalDelegateHandling = NO;
            
            
        else
            NSLog(@"normal launch");
            // normal app launch process without quick action
            
            // [self launchWithoutQuickAction];
            
        
        
    else
        
        // Less than iOS9 or later
        
        //  [self launchWithoutQuickAction];
        
    
    
    
    return shouldPerformAdditionalDelegateHandling;



- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
    NSLog(@"performActionForShortcutItem");
    
    BOOL handledShortCutItem = [self handleShortCutItem:shortcutItem];
    
    completionHandler(handledShortCutItem);



/**
 *  @brief handle shortcut item depend on its type
 *
 *  @param shortcutItem shortcutItem  selected shortcut item with quick action.
 *
 *  @return return BOOL description
 */
- (BOOL)handleShortCutItem : (UIApplicationShortcutItem *)shortcutItem
    
    BOOL handled = NO;
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    
    
    if ([shortcutItem.type isEqualToString:@"PlayMusic"]) 
        handled = YES;
        NSLog(@"Play");
        
        secondview *vc = [storyboard instantiateViewControllerWithIdentifier:@"second"];
        
        self.window.rootViewController = vc;
        
        [self.window makeKeyAndVisible];
        
    
    
    else if ([shortcutItem.type isEqualToString:@"StopMusic"]) 
        handled = YES;
        NSLog(@"Stop");
        //        ThirdViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"thirdVC"];
        //
        //        self.window.rootViewController = vc;
        
        [self.window makeKeyAndVisible];
    
    
    
    return handled;

但是,当我深按主页图标但单击时没有任何操作发生时,我可以看到快速操作项目。我检查了 info.plist 中的密钥和它的相同。 Quick Actions

下面是添加静态动作的 info.plist

<key>UIApplicationShortcutItems</key>
<array>
    <dict>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypePlay</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Play</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Start playback</string>
        <key>UIApplicationShortcutItemType</key>
        <string>PlayMusic</string>
    </dict>
    <dict>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypePlay</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>STOP</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Stop playback</string>
        <key>UIApplicationShortcutItemType</key>
        <string>StopMusic</string>
    </dict>

有人可以帮我解决我做错的地方吗?

【问题讨论】:

【参考方案1】:

由于iOS(13.0, *) AppDelegate 通过SceneDelegate 等方法处理自己的UIWindow

@implementation AppDelegate

-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler

    // here shortcut evaluation below ios(13.0)


@end

仅在 iOS 较低版本 13.0 的 iPhone 或 iPad 上调用

因此,要使其在 iOS(13.0,*) 及更高版本中运行,您需要在 SceneDelegate 中使用稍微不同的名称来实现它,见下文.. (马特是对的!)

@implementation SceneDelegate

-(void)windowScene:(UIWindowScene *)windowScene performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler 
    // here shortcut evaluation starting with ios(13.0)
    NSLog(@"shortcutItem=%@ type=%@",shortcutItem.localizedTitle, shortcutItem.type);


@end

PS:当你假设你可以在 iOS(13.0,*) 中使用它时,Apple Swift 中的快速操作示例代码是虚假的,因为它是为早期的 iO​​S 版本编写的

编辑:按照要求,iOS >= 13.0

@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
@property (strong, nonatomic) UIWindow * window;
@end

-(void)windowScene:(UIWindowScene *)windowScene performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler 
    /* //go to Info.plist open as Source Code, paste in your items with folling scheme
    <key>UIApplicationShortcutItems</key>
    <array>
        <dict>
            <key>UIApplicationShortcutItemIconType</key>
            <string>UIApplicationShortcutIconTypePlay</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>Play</string>
            <key>UIApplicationShortcutItemSubtitle</key>
            <string>Start playback</string>
            <key>UIApplicationShortcutItemType</key>
            <string>$(PRODUCT_BUNDLE_IDENTIFIER).Start</string>
        </dict>
        <dict>
            <key>UIApplicationShortcutItemIconType</key>
            <string>UIApplicationShortcutIconTypePlay</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>STOP</string>
            <key>UIApplicationShortcutItemSubtitle</key>
            <string>Stop playback</string>
            <key>UIApplicationShortcutItemType</key>
            <string>$(PRODUCT_BUNDLE_IDENTIFIER).Stop</string>
        </dict>
    </array>
     */
    
    // may look complex but this is 100% unique
    // which i would place $(PRODUCT_BUNDLE_IDENTIFIER). in front of types in Info.plist
    NSString *devIdent = [NSString stringWithFormat:@"%@.",NSBundle.mainBundle.bundleIdentifier];
    
    if ([shortcutItem.type isEqualToString:[devIdent stringByAppendingString:@"Start"]]) 
        completionHandler([self windowScene:windowScene byStoryBoardIdentifier:@"startview"]);
        
     else if ([shortcutItem.type isEqualToString:[devIdent stringByAppendingString:@"Stop"]]) 
        completionHandler([self windowScene:windowScene byStoryBoardIdentifier:@"stopview"]);

     else 
        NSLog(@"Arrgh! unrecognized shortcut '%@'", shortcutItem.type);
    
    //completionHandler(YES);


-(BOOL)windowScene:(UIWindowScene *)windowScene byStoryBoardIdentifier:(NSString *)identifier 
    // idear is to return NO if build up fails, so we can startup normal if needed.
    UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    if (story!=nil) 
        UIViewController *vc = [story instantiateViewControllerWithIdentifier:identifier];
        if (vc!=nil) 
            if (_window==nil) _window = [[UIWindow alloc] initWithWindowScene:windowScene];
            _window.rootViewController = vc;
            
            // .. OR following code..
            //[_window.rootViewController presentViewController:vc animated:YES completion:^ ];
            //[_window makeKeyAndVisible];
            
            // should be success here..
            return YES;
        
    
    // no success here..
    return NO;

除了从 Storyboard 实例化 ViewController 之外,您还可以做其他事情。例如,您可以切换属性或类似的东西。

【讨论】:

非常感谢....能否请您发布静态快速操作项目的完整代码?我已经发布了有问题的完整代码,但它不起作用。 任何票数 :-) 对于 swift 编码器 matt's post follows the apple example 和 BundleIdentifier in swift here 我已投票(仅在我的 15 分后显示)并接受了您的回答 :)。你能告诉我如何从快捷操作推送到某个视图控制器吗? 一个 GitHub 示例项目(快速操作),iOS 13 及以上版本都对我有帮助 那是帖子中 co-method 中被注释掉的部分,改用它,它应该在前面展示你的 VC。 [_window.rootViewController presentViewController:vc animated:YES completion:^ ]; 而不是 _window.rootViewController = vc;【参考方案2】:

抱歉来晚了。在与主要开发人员讨论后,对家庭快速操作的进一步研究向我展示了以下结论。在集成 HomeQuickActions 时需要遵循以下几点:

    对每个开发者来说最重要的一点: 主页快速操作(点击应用图标的快捷方式)绝对是基于操作系统和硬件的(仅从 iOS 13 开始支持)。 Apple documents。这意味着在 iOS 13 之前,即使有 Haptic Touch / 3D Touch 设备也不会显示应用快捷方式项目。 iOS 13 及以上是强制性要求。(所有 iPhone 都在模拟器中检查,需要在旧手机的真机上测试)

启用 3D 触控和未启用 3D 触控的设备都通过强制触控或长按来支持此功能,具体取决于设备功能(如果它们能够运行 iOS 13 或更高版本)。

    因此,要使 App 快捷方式正常工作,iOS 设备必须肯定具有 iOS 13,并且还需要硬件兼容性,这意味着设备必须具有 iOS 13 及更高版本才能使 App 快捷方式工作。 iPhone 5S、iPhone 6 用户:iOS 13 将不再兼容。

    由于 Apple 已将 3D Touch 硬件替换为 Haptic Touch,iPhone XR 的新款 iPhone 将仅配备 Haptic Touch。 SE(第一代,iPhone 6 系列直到 iPhone X)之后的旧设备具有 3D Touch 硬件。 Haptic Touch 是依赖于软件操作系统的,它使用手指按下的区域,而 3D Touch 是依赖于硬件的,它在屏幕之间使用特定的传感器。

【讨论】:

感谢 Fiona 提供如此重要的说明。 :) 当然,iOS 13 plus 是应用快捷方式工作的强制性要求。

以上是关于静态快速​​操作在目标 c iOS 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

animateWithDuration 在 vi​​ewWillAppear ios 9 目标 c 中不起作用

目标 =“_blank” 在 IOS 中不起作用

UITableView 内容“静态单元格”在 iOS7 中不起作用

导航在目标 c 中不起作用

Dlib 正面人脸检测在 IOS 中不起作用。?

UITableViewCell 选择在目标 c 中不起作用