首页 > 解决方案 > 静态快速​​操作在目标 c iOS 中不起作用

问题描述

我对 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 中的密钥和它的相同。 快速操作

下面是添加静态动作的 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>

有人可以帮助我做错了吗?

标签: iosobjective-ciphonexcode3dtouch

解决方案


因为iOS(13.0, *)AppDelegate 处理自己的UIWindowviaSceneDelegate等方法

@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, *)中按原样使用它时,Swift 中快速操作的 Apple 示例代码是伪造的,因为它是为早期 iOS < 13.0 的版本编写的

编辑:如被问及,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 之外,您还可以做其他事情。例如,您可以切换属性或类似的东西。


推荐阅读