Вопрос или проблема
Действия ярлыков приложений не отображаются в приложении ярлыков iOS 18
Во-первых, прошу прощения, если мой английский не очень хорош.
Мы разработали iOS-приложение на Objective-C и добавили интеграции для приложения “Команды” – более конкретно, для его части “Автоматизация”.
По сути, пользователь открывает приложение “Команды”, выбирает автоматизацию, и при сканировании NFC-метки пользователь может выбрать действие, и наше приложение показывает 3 различных действия. Пользователь выбирает действие, открывает приложение, и действие выполняется. Все это было реализовано на Obj-C и работало очень хорошо без жалоб, пока пользователи не начали обновляться до iOS 18.
Теперь, когда пользователь начинает добавлять автоматизацию, единственное, что они могут сделать, это выбрать “открыть приложение”. Действия нашего приложения больше не отображаются. Есть ли что-то новое в iOS 18, что нам нужно обновить в нашем приложении?
Я знаю, что Objective-C считается “старым”, но стоимость обновления существующего приложения и время на это сейчас недоступны.
Вот фрагмент кода нашего shortcutIntent:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.lw.grp1</string>
<string>group.lw.grp2</string>
</array>
</dict>
</plist>
Info-plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsRestrictedWhileLocked</key>
<array/>
<key>IntentsRestrictedWhileProtectedDataUnavailable</key>
<array/>
<key>IntentsSupported</key>
<array>
<string>LockIntent</string>
<string>TrunkIntent</string>
<string>UnlockIntent</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.intents-service</string>
<key>NSExtensionPrincipalClass</key>
<string>IntentHandler</string>
</dict>
</dict>
</plist>
IntentHandler
@implementation IntentHandler
-(id)init{
self = [super init];
self.started = false;
self.handler = [[AppIntentHandler alloc] init];
self.handler.userInfo = [[NSMutableDictionary alloc] init];
return self;
}
- (id)handlerForIntent:(INIntent *)intent {
// Это стандартная реализация. Если вы хотите, чтобы разные объекты обрабатывали разные намерения,
// вы можете переопределить это и вернуть обработчик, который вы хотите для этого конкретного намерения.
if(!self.started){
self.started = YES;
if([intent isKindOfClass:[LockIntent class]]){
NSLog(@"*выбрано намерение блокировки*");
self.handler.userInfo = [self assignUserInfo:@"lock"];
}else if([intent isKindOfClass:[UnlockIntent class]]){
NSLog(@"*выбрано намерение разблокировки*");
self.handler.userInfo = [self assignUserInfo:@"unlock"];
}else if([intent isKindOfClass:[TrunkIntent class]]){
NSLog(@"*выбрано намерение багажника*");
self.handler.userInfo = [self assignUserInfo:@"trunk"];
}
}else{
self.started = NO;
}
return self.handler;
}
Пользовательский класс для обработки каждого намерения
@interface AppIntentHandler : NSObject<LockIntentHandling, UnlockIntentHandling, TrunkIntentHandling>
@implementation AppIntentHandler
#pragma mark - обработчики ответов
- (void)handleLock:(nonnull LockIntent *)intent completion:(nonnull void (^)(LockIntentResponse * _Nonnull))completion {
LockIntentResponse *response = [[LockIntentResponse alloc] initWithCode:LockIntentResponseCodeContinueInApp userActivity:[self lockUserActivity]];
completion(response);
}
- (void)handleUnlock:(nonnull UnlockIntent *)intent completion:(nonnull void (^)(UnlockIntentResponse * _Nonnull))completion {
UnlockIntentResponse *response = [[UnlockIntentResponse alloc] initWithCode:UnlockIntentResponseCodeContinueInApp userActivity:[self unlockUserActivity]];
completion(response);
}
- (void)handleTrunk:(nonnull TrunkIntent *)intent completion:(nonnull void (^)(TrunkIntentResponse * _Nonnull))completion {
TrunkIntentResponse *response = [[TrunkIntentResponse alloc] initWithCode:TrunkIntentResponseCodeContinueInApp userActivity:[self trunkUserActivity]];
completion(response);
}
Что нужно сделать, чтобы действия нашего приложения снова отображались в приложении “Команды”? Заранее спасибо.
Ответ или решение
Ваш вопрос касается проблем совместимости вашего iOS приложения с приложением "Команды" (Shortcuts app) в iOS 18. Давайте рассмотрим несколько аспектов, которые могут помочь вам восстановить функциональность вашего приложения.
1. Проверка настроек Info.plist
Убедитесь, что все необходимые ключи в вашем Info.plist
файле правильно настроены. В вашем случае вы указали поддержку LockIntent
, UnlockIntent
и TrunkIntent
. Проверьте следующее:
- Все необходимые intents должны быть зарегистрированы в
IntentsSupported
массиве. - Убедитесь, что вы используете правильный тип
NSExtensionPointIdentifier
. Это должно бытьcom.apple.intents-service
, и это, похоже, у вас настроено правильно.
2. Проверка реализации IntentHandler
Проверьте, что ваша реализация IntentHandler
корректно возвращает обработчик для каждого конкретного намерения. Ваша логика обработки намерений выглядит правильно, но стоит убедиться, что класса LockIntent
, UnlockIntent
и TrunkIntent
работают корректно и соответствуют последним изменениям в Apple Developer Documentation.
3. Использование новых функций iOS 18
iOS 18 может вводить новые настройки или требовать больше информации от приложений для интеграции с "Командами". Проверьте последние обновления в Apple Developer Documentation на предмет изменений в API Shortcuts. Убедитесь, что ваш проект обновлён для поддержки новых требований.
4. Перепроверка тестирования на реальном устройстве
Проблема может быть специфичной для вашего тестирования на устройстве. Попробуйте протестировать вашу автоматизацию на нескольких устройствах с iOS 18, чтобы исключить возможность ошибки в настройках конкретного устройства.
5. Убедитесь в наличии всех разрешений
Ваше приложение может требовать определённых разрешений для работы с NFC или интентами. Убедитесь, что все запрашиваемые пользователем разрешения были предоставлены и активированы.
6. Логирование
Добавьте дополнительное логирование в ваш код, чтобы отследить, какие намерения обрабатываются и где может происходить сбой. Это может помочь в диагностике проблемы при вызове вашего IntentHandler
.
7. Обновление Документации
Если ваша разработка была основана на старой документации, обязательно просмотрите последнюю информацию и примеры кода. Возможно, что Apple внесла изменения, которые могут повлиять на работу вашего приложения в iOS 18.
Теперь, если все эти шаги не помогут, возможно, стоит рассмотреть возможность обновления вашего приложения на Swift или другой более современный язык, чтобы обеспечить долгосрочную совместимость и возможность использования всех новых функций и улучшений платформы iOS.
Если у вас есть дополнительные вопросы или вам требуется больше информации по какому-то из пунктов, не стесняйтесь задавать вопросы.