静态快速操作在 objective c iOS 中不起作用
Static Quick Actions not working in objective 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 中的密钥,它是相同的。
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>
有人可以帮助我哪里做错了吗?
因为 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 中使用略有不同的名称来实现它,请参见下文.. (matt 是对的! )
@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,*) 因为它是为更早的版本编写的 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 之外,您还可以做其他事情。例如,您可以切换 属性 或类似的东西。
抱歉来不及了。在与主要开发人员讨论后,我对主页快速操作的进一步研究显示出以下结论。集成 HomeQuickActions 需要遵循以下几点:
- 对每个开发人员最重要的一点: 首页快速操作(点击应用程序图标的快捷方式)是绝对 OS 和基于硬件(仅支持 iOS 13)。 Apple documents。这意味着在 iOS 13 之前,没有设备会显示应用程序快捷方式项目,即使它们具有 Haptic Touch / 3D Touch。 iOS 13及以上是强制性要求。(在模拟器中检查了所有iPhone,需要在旧手机的真实设备中测试)
支持 3D 触摸和不支持 3D 触摸的设备均通过强制触摸或长按来支持此功能,具体取决于设备功能(如果它们能够 运行 iOS 13 或更高)。
因此,要使应用程序快捷方式正常工作,iOS 设备必须具有 iOS 13,并且还需要硬件兼容性,这意味着设备必须具有 iOS 13 及以上才能使应用程序快捷方式正常工作。对于iPhone 5S,iPhone 6 位所有者:iOS 13 将不再兼容。
由于 Apple 已将 3D Touch 硬件替换为 Haptic Touch,因此来自 iPhone XR 的较新 iPhones 将只有 Haptic Touch。 SE(第 1 代,iPhone 6 系列直到 iPhone X )之后的旧设备具有 3D Touch 硬件。 Haptic Touch 是一种依赖于软件 OS 的软件,它使用手指按下的区域,而 3D Touch 是一种依赖于硬件的软件,它使用屏幕之间的特定传感器。
我是 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>
有人可以帮助我哪里做错了吗?
因为 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 中使用略有不同的名称来实现它,请参见下文.. (matt 是对的! )
@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,*) 因为它是为更早的版本编写的 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 之外,您还可以做其他事情。例如,您可以切换 属性 或类似的东西。
抱歉来不及了。在与主要开发人员讨论后,我对主页快速操作的进一步研究显示出以下结论。集成 HomeQuickActions 需要遵循以下几点:
- 对每个开发人员最重要的一点: 首页快速操作(点击应用程序图标的快捷方式)是绝对 OS 和基于硬件(仅支持 iOS 13)。 Apple documents。这意味着在 iOS 13 之前,没有设备会显示应用程序快捷方式项目,即使它们具有 Haptic Touch / 3D Touch。 iOS 13及以上是强制性要求。(在模拟器中检查了所有iPhone,需要在旧手机的真实设备中测试)
支持 3D 触摸和不支持 3D 触摸的设备均通过强制触摸或长按来支持此功能,具体取决于设备功能(如果它们能够 运行 iOS 13 或更高)。
因此,要使应用程序快捷方式正常工作,iOS 设备必须具有 iOS 13,并且还需要硬件兼容性,这意味着设备必须具有 iOS 13 及以上才能使应用程序快捷方式正常工作。对于iPhone 5S,iPhone 6 位所有者:iOS 13 将不再兼容。
由于 Apple 已将 3D Touch 硬件替换为 Haptic Touch,因此来自 iPhone XR 的较新 iPhones 将只有 Haptic Touch。 SE(第 1 代,iPhone 6 系列直到 iPhone X )之后的旧设备具有 3D Touch 硬件。 Haptic Touch 是一种依赖于软件 OS 的软件,它使用手指按下的区域,而 3D Touch 是一种依赖于硬件的软件,它使用屏幕之间的特定传感器。