Flutter / Swift Compiler Error (Xcode): Cannot find 'ExternalLinkAccount' in scope - ios

Since 12th october 2022, reader's app with external account management/purchase must have to declare a new entitlement.
External Link Account
Enable qualifying apps to link to an external website for account creation or management.
https://developer.apple.com/documentation/storekit/external_link_account
I can't build because :
Swift Compiler Error (Xcode): Cannot find 'ExternalLinkAccount' in scope
Configure the SKExternalLinkAccount property list key.
<plist>
<dict>
<key>SKExternalLinkAccount</key>
<dict>
<key>*</key>
<string>https://example.com</string>
<key>jp</key>
<string>https://example.com/jp</string>
</dict>
</dict>
</plist>
Runner plist
<key>com.apple.developer.storekit.external-link.account</key>
<true/>
Runner entitlement
<plist>
<dict>
<key>com.apple.developer.storekit.external-link.account</key>
<true/>
</dict>
</plist>
ios build (with flutter run) :
Swift Compiler Error (Xcode): Cannot find 'ExternalLinkAccount' in scope
My code in a custom swift file (called with a platform specific call)
import SwiftUI
struct ExternalLinkAccountModal: View {
var body: some View {
Text("Hello, world!")
.padding()
.onAppear {
Task {
await executeTask()
}
}
}
}
struct ExternalLinkAccountModal_Previews: PreviewProvider {
static var previews: some View {
ExternalLinkAccountModal(onConfirm: nil, onCancel: nil)
.previewDevice("iPhone 13")
.previewInterfaceOrientation(.portrait)
}
}
func executeTask() async {
let basicTask = Task {
if await ExternalLinkAccount.canOpen {
do {
try await ExternalLinkAccount.open()
} catch {
print("ExternalLinkAccount.open() error \(error)")
}
}
}
}
Provisioning profile
My provisioning profile is well configured and accepted by Apple Developper :
Associated Domains, External Link Account, In-App Purchase, Push Notifications
Can you help to fix this ?
I'm using osx Ventura and ios16 platform for developping.

Related

Adding CarPlay to a SwiftUI lifecycle app

What is the recommended way to integrate CarPlay into an app which uses a SwiftUI lifecycle ?
#main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
How do I use the CPTemplateApplicationSceneDelegate here ?
If you don't have a custom app delegate and/or scene delegate (you might need it eventually for stuff like push notifications) it should be enough to let your app know via the info.plist. You need a scene delegate for the CarPlay scene and add the following to your info.plist:
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>CPTemplateApplicationSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>CPTemplateApplicationScene</string>
<key>UISceneConfigurationName</key>
<string>TemplateSceneConfiguration</string>
<key>UISceneDelegateClassName</key>
<string>AppFeature.CarPlaySceneDelegate</string>
</dict>
</array>
</dict>
</dict>
The value for UISceneConfigurationName is handed to you in the scene delegate's scene(_:willConnectTo:options:) session.configuration.name.
The value for UISceneDelegateClassName has to match your CarPlay scene delegate's Type name. Note that if you encapsulate your CarPlay code in a package/framework you need to prefix the delegate's name with the module name (in this case AppFeature). If the delegate is in your app target just use CarPlaySceneDelegate.
An excerpt of the scene delegate might look like this:
class CarPlaySceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate {
let templateManager = TemplateManager() // see Apple's sample code
func templateApplicationScene(_: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController) {
templateManager.connect(interfaceController)
}
func templateApplicationScene(_: CPTemplateApplicationScene, didDisconnectInterfaceController _: CPInterfaceController) {
templateManager.disconnect()
}
}

Unable to call Device Activity in Screen Time Api From Parent Device

Using shared authorization I am able to authorize the child's device and able to see all the installed apps on the child's mobile on the parent device. But when I am trying to call DeviceActivity nothing happens. This is how I am calling DeviceActivity
class MyDeviceActivityMonitor: DeviceActivityMonitor{
override func intervalDidStart(for activity: DeviceActivityName) {
super.intervalDidStart(for: activity)
}
override func intervalDidEnd(for activity: DeviceActivityName) {
super.intervalDidEnd(for: activity)
}
override func eventDidReachThreshold(_ event:DeviceActivityEvent.Name,activity:DeviceActivityName){
super.eventDidReachThreshold(event, activity: activity)
}
}
info.plist
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.deviceactivity.monitor-extension</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).DeviceActivityMonitorExtension</string>
</dict>
I am stuck in this issue too. Have you tried changing the NSExtensionPrincipalClass to the below?
<string>$(PRODUCT_MODULE_NAME).MyDeviceActivityMonitor </string>

facebook and google login open in application by sfsafariviewcontroller

In my app user can login with facebook and google account. but when user click on facebook login or google login he will redirect to safari browser. So apple reject my app with below reason.
We noticed that the user is taken to Safari to sign in or register for an account, which provides a poor user experience. Next Steps To resolve this issue, please revise your app to enable users to sign in or register for an account in the app.
For resolving the issue I added facebook login behavior as the web "FBSDKLoginBehaviorWeb". Now when I open it, it is opening in the app only. but when I click on "Not Now" button on here is the facebook screen shot facebook it is crashing my app in the second time. Can anyone have answer to this issue? Also, can any one suggest me how do I solve the google sign on the issue too?
Try this :
Swift 4.0 snippet:
let loginManager = FBSDKLoginManager()
loginManager.logIn(withReadPermissions: ["email","public_profile"], from: self) { (result, error) in
if ((error) != nil) {
// Process error
} else if (result?.isCancelled)! {
// Handle cancellations
} else {
// If you ask for multiple permissions at once, you
// should check if specific permissions missing
if (FBSDKAccessToken.current() != nil)
{
FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email, name"]) .start(completionHandler: { (connectioon, result, error) in
if error == nil
{
print(result);
}
})
}
}
}
Make sure you have added these below items in info.plist:
1.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
2.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fbxxxxxxxxxxxxxx</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>xxxxxxxxxxxx</string>
<key>FacebookDisplayName</key>
<string>App name</string>
Note: iOS should be greater than iOS 9.0 or later to use SFSafariViewController.
Try to handle is cancelled , also i use facebook sdk version 4.17.0
and click not know and works perfectly
facebookLogin.logIn(withReadPermissions: ["public_profile","email", "user_friends"], from:self, handler:
{
(facebookResult, facebookError) -> Void in
if facebookError != nil
{
print("Facebook login failed. Error \(String(describing: facebookError))")
}
else if (facebookResult?.isCancelled)!
{
print("Facebook login was cancelled.")
}
else
{
// success
}
});
see in action

Can't get an item's attributes from a DynamoDB table

I have an iOS app written in Swift. In this app I'm trying to load an item from a DynamoDB table, but for some reason, I couldn't load any item, even though all the details were correct.
I have installed the AWS SDK using CocoaPods, after I followed all the instructions in order to correctly install it. I have installed the following libraries: AWSCognito, AWSCognitoIdentityProvider, AWSDynamoDB, AWSS3, AWSSNS.
After that, I have added my AWS credentials in the Info.plist file:
<key>AWS</key>
<dict>
<key>DynamoDBObjectMapper</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>USEast1</string>
</dict>
</dict>
<key>DynamoDB</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>USEast1</string>
</dict>
</dict>
<key>CredentialsProvider</key>
<dict>
<key>CognitoIdentity</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>USEast1</string>
<key>PoolId</key>
<string>myPoolId</string>
</dict>
</dict>
</dict>
</dict>
I've created a mapper file called Contact.swift:
import UIKit
import AWSDynamoDB
class Contact: AWSDynamoDBObjectModel, AWSDynamoDBModeling {
var id: String?
var name: String?
class func dynamoDBTableName() -> String {
return "Contacts"
}
class func hashKeyAttribute() -> String {
return "id"
}
}
Then, I've added the following code in ViewController.swift file, inside the viewDidLoad method. The code should get an item from a table, save its attributes, and set its name attribute to be the title of the screen:
import UIKit
import AWSDynamoDB
class ViewController: UIViewController {
//MARK: Properties
struct GlobalVars {
static let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
static let id: String = "id"
static var name: String?
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
GlobalVars.dynamoDBObjectMapper.load(Contact.self, hashKey: GlobalVars.id, rangeKey: nil).continueWith(block: {(task: AWSTask<AnyObject>!) -> Any? in
if let error = task.error as NSError? {
print("The request failed. Error: \(error)")
} else if let taskResult = task.result as? Contact {
// Save the information
GlobalVars.name = taskResult.name
// Set title to the name
self.navigationItem.title = GlobalVars.name!
}
return nil
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The problem is that the app crashes when I'm trying to assign the GlobalVars.name variable to the navigation bar title. It crashes with the following message: Fatal error: Unexpectedly found nil while unwrapping an Optional value.
I've tried to print taskResult.name instead, but it just printed nil.
But it didn't print anything to the console. I've added the following code to the Info.plist file, but that didn't work also:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>amazonaws.com</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>amazonaws.com.cn</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
When I'm checking in the variables area at the bottom of the editor, I can see that all of the item's attributes are nil.
After a deep search, I've noticed something very weird. When I changed the name of the table to a table which doesn't exist, I have received the following message in the console:
The request failed. Error: Error Domain=com.amazonaws.AWSDynamoDBErrorDomain Code=7 "(null)" UserInfo={__type=com.amazonaws.dynamodb.v20120810#ResourceNotFoundException, message=Requested resource not found}
When I'm running it with a correct table name, but with a wrong hash key which refers to an item which doesn't exist in the table, I don't get anything. It doesn't crashes or prints a message to the console. It just keeps running like I'm don't asking for anything from the DynamoDB table.
What can I do about it? I've already searched all over the internet but I couldn't find anything about it yet... Could you please help me solving that?
So apparently, due to a change in Swift 4 behavior change of inferencing #objc, I was supposed to add #objcMembers before the class declaration in the Contact.swift file

My app does not appear in the iOS notification center - Appcelerator

I'm having serious headaches with push for iOS with titanium appcelerator.
I generated several versions in testflight, but none of them appear in the iOS notification center, however, when I swipe directly into the device, it works normally on my iPad Mini.
I am currently using these settings:
Operating System
Name = Mac OS X
Version = 10.12
Architecture = 64bit
# CPUs = 4
Memory = 4294967296
Node.js
Node.js Version = 4.6.0
npm Version = 2.15.9
Titanium CLI
CLI Version = 5.0.9
Titanium SDK
SDK Version = 5.5.1.GA
SDK Path = /Users/silvio/Library/Application Support/Titanium/mobilesdk/osx/5.5.1.GA
Target Platform = iphone
Xcode Version: 8.2 (8C38)
My code in Alloy.js:
if (Ti.Platform.name === 'android') {
// set android-only options
var pnOptions = {
senderId: 'xxxx', // It's the same as your project id
notificationSettings: {
sound: 'mysound.mp3', // Place soudn file in platform/android/res/raw/mysound.mp3
smallIcon: 'appicon.png', // Place icon in platform/android/res/drawable/notification_icon.png
largeIcon: 'appicon.png', // Same
vibrate: true, // Whether the phone should vibrate
insistent: true, // Whether the notification should be insistent
group: 'Edufy', // Name of group to group similar notifications together
localOnly: false, // Whether this notification should be bridged to other devices
priority: 2 // Notification priority, from -2 to 2
}
};
} else { // set ios-only options.
// Sets interactive notifications as well if iOS8 and above. Interactive notifications is optional.
if (parseInt(Ti.Platform.version.split(".")[0], 10) >= 8) {
var thumbUpAction = Ti.App.iOS.createUserNotificationAction({
identifier: "THUMBUP_IDENTIFIER",
title: "Aceitar",
activationMode: Ti.App.iOS.USER_NOTIFICATION_ACTIVATION_MODE_BACKGROUND,
destructive: false,
authenticationRequired: false
});
var thumbDownAction = Ti.App.iOS.createUserNotificationAction({
identifier: "THUMBDOWN_IDENTIFIER",
title: "Regeitar",
activationMode: Ti.App.iOS.USER_NOTIFICATION_ACTIVATION_MODE_BACKGROUND,
destructive: false,
authenticationRequired: false
});
var thumbUpDownCategory = Ti.App.iOS.createUserNotificationCategory({
identifier: "THUMBUPDOWN_CATEGORY",
// The following actions will be displayed for an alert dialog
actionsForDefaultContext: [thumbUpAction, thumbDownAction],
// The following actions will be displayed for all other notifications
actionsForMinimalContext: [thumbUpAction, thumbDownAction]
});
var pnOptions = {
types: [Ti.App.iOS.USER_NOTIFICATION_TYPE_ALERT, Ti.App.iOS.USER_NOTIFICATION_TYPE_SOUND],
categories: [thumbUpDownCategory]
};
} else { //No support for interactive notifications, omit categories
var pnOptions = {
types: [Ti.App.iOS.USER_NOTIFICATION_TYPE_ALERT, Ti.App.iOS.USER_NOTIFICATION_TYPE_SOUND]
};
}
}
// set cross-platform event
var onReceive = function(event) {};
// Create instance with base url
var tiPush = require('ti-push-notification').init({
backendUrl: "http://xxxx.com.br/painel/ws/push_test.php"
});
// register this device
tiPush.registerDevice({
pnOptions: pnOptions,
onReceive: onReceive,
extraOptions: {
action: 'register',
user_id: 123
}
});
My certificates in the apple store are all valid, as in the prints below:
Push Notifications Enabled:
Certificates:
Prov Profiles:
Also, I tried adding the Entitlements.plist in these locations:
Project / Entitlements.plist
Project / app / Entitlements.plist
Project / app / platform / ios / Entitlements.plist
Project / app / platform / ios / .plist
I also added the lines from within the tag to tiapp.xml, but it did not work ... below the Entitlements.plist code:
<?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>aps-environment</key>
<string>development</string> <!-- Either development or production -->
<key>application-identifier</key>
<string>xxxx.com.colegiokennedy</string>
<key>keychain-access-groups</key>
<array>
<string>xxx.com.colegiokennedy</string>
</array>
</dict>
</plist>
I've also tried changing the development environment to production, but it did not work too.
You can try including Ti.App.iOS.USER_NOTIFICATION_TYPE_BADGE.
Make sure that in your iOS device, go to Settings -> Notifications -> Your_App -> Show in Notification Centre is selected. You can check that what kind of settings are on/off for your app's notifications.

Resources