iOS8 extension unable to use AFNetworking library - afnetworking

I am unable to use AFNetworking library in my app extension due to
that was trying to access the UIApplication class methods. Does any
one knows here any other better network library that does not access
UIApplication class?. Please suggest.

quote from Guard for unsupported features of iOS 8 extensions #2589
To fix this issue i had to put AF_APP_EXTENSIONS=1 as a preprocessor
macro for the Pods-hitta.se WatchKit Extension-AFNetworking target.
Adding #define AF_APP_EXTENSIONS to the prefix header didn't work,
neither did adding it as a preprocessor macro to the watch extension
target work.
So click on Pods project in Project Navigator, then select Pods-{your-app-name-extension}-AFNetworking. Next go to Build Settings and find Preproccessor Macros where you add new line with "AF_APP_EXTENSIONS=1"
Also wrap it with +#if !defined(AF_APP_EXTENSIONS) at beginning. And end it +#endif
full example of wrapping:
- (void)updateNetworkActivityIndicatorVisibility {
+#if !defined(AF_APP_EXTENSIONS)
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]];
+#endif
}

You can use AFNetworking with extension. You just need follow the instruction below.
When using AFNetworking in an App Extension, #define AF_APP_EXTENSIONS
to avoid using unavailable APIs.
https://github.com/AFNetworking/AFNetworking/issues/2119

Related

ITMS-90842: Invalid SDK usage with AppClip and Flutter

Until I upload myapp to appstore
I have this issue:
Please correct the following issues, then upload again.
ITMS-90842: Invalid SDK usage - App clip
'Runner.app/AppClips/RunnerAppClip.app' uses the SDK selector
'requestAlwaysAuthorization', which is not supported. Ensure your app clip is
using supported SDK features.
I am used location permission but how exclude specific location from AppClip
You can include/exclude specific lines of code from your App Clip target using a Swift Compilation Flag.
To do this you can open the Build Settings of your App Clip target and add some custom flag like APPCLIP.
Then in your code...
#if !APPCLIP
//Location code that uses `requestAlwaysAuthorization`
#endif

In Swift, how to ignore a part of the code when running from an App Extension target?

There's a similar question that works on Objective-C, but I tried the same code in Swift and it never executes, neither in the main app, nor in the action extension.
My situation is similar to the one in the question above, that is, when running from the main app I want to use UIApplication.shared.open to open a link in Safari, but I want to ignore this part of the code on the App Extension.
The problem isn't finding out whether the app is running from an App Extension or not, but ignoring the code when building for the App Extension, so that the compiler does not give me the following error on build:
You could introduce a new Custom Flag (similar to the DEBUG flag) for the extension target. In your Build Settings look for the Custom Flags and add a new one (e.g. "EXTENSION"). Like here in the screenshot, but also do it for release.
In your Code you could then do something like
#if EXTENSION
// here goes code that is only compiled in the extension
#else
// here goes code that is only compiled outside the extension
#endif
Update: Please read the Apple provided documentation on App Extensions:
Some APIs Are Unavailable to App Extensions
Because of its focused role in the system, an app extension is ineligible to participate in certain activities. An app extension cannot:
Access a Application.shared object, and so cannot use any of the methods on that object
- Apple, App Extension Programming Guide
To programmatically find if the it the running extension via code it's really simple, just do this:
let bundleUrl: URL = Bundle.main.bundleURL
let bundlePathExtension: String = bundleUrl.pathExtension
let isAppex: Bool = bundlePathExtension == "appex"
// `true` when invoked inside the `Extension process`
// `false` when invoked inside the `Main process`

Using pushwoosh with multiple target apps

I have an IOS application which has two targets, and each target has its own .plist file... I thought pushwoosh would get the "Pushwoosh_APPID" from the .plist which my target is set but it didn't actually...
Is there a way to set pushwoosh to get the "Pushwoosh_APPID" from another .plist file?
thanks!
You can also initialize PushNotificationManager with the following code:
+ (void)initializeWithAppCode:(NSString *)appCode appName:(NSString *)appName;
I.e.
[PushNotificationsManager initializeWithAppCode:#"XXXX-XXXX" appName:#"AppName"];
Do this first thing in didFinishLaunchingWithOptions function.

Use UIKit conditionally in file used by Watch app

I have created a model class that I use in my iOS app and my Watch app - it is included in both targets. Now I have to use UIPasteboard in this class which is only available in UIKit, which is not available to watchOS. While I can import UIKit into this file without issue, when I go to use UIPasteboard it will not compile because the watch extension does not know about it.
How can I use UIPasteboard in a class that is available to my watch app?
I wondered if I could only run that code when the device isn't an Apple Watch by using #available, but this didn't resolve the issue.
if #available(iOS 7.0, *) {
UIPasteboard.generalPasteboard()...
//ERROR: Use of unresolved identifier 'UIPasteboard'
} else {
//don't use UIPasteboard
}
Use the existing preprocessor directive defined in Swift:
#if os(iOS)
//UIKit code here
#elseif os(watchOS)
//Watch code here
#endif
See the documentation for preprocessor directives here.
Maybe you could use an extension to factor out the UIPasteboard functionality and include the file containing the extension only in the iPhone target.
Ideally, code shared by several OS's should contain only truly shared code.
Also, if you want the conditionality, this is probably a cleaner way to do it.
There are two ways to do so.
First way is using preprocessor directives, like the following example:
#if os(iOS)
//Insert UIKit (iOS) code here
#elseif os(watchOS)
//Insert WatchKit (watchOS) code here
#endif
The second way is to determine if the code is called from the WatchKit Extension or iOS App. For example, you can set a global boolean flag to true before calling the code from WatchKit Extension, and false before calling from iOS App. Then the shared code can check the value of the flag to determine it is running on iOS or watchOS.

Unrecognized selector sent to instance when attempting to call an extension method via a swift bridging header

I'm trying to call Objective-C code from Swift. I created a Swift Bridging Header, and added an import to the Objective-C file (e.g. #import "UIColor+Utils.h").
The project builds, and I even get code completion, but when it attempts to execute that line of code, it crashes and says unrecognized selector sent to class.
What did I do wrong?
(Xcode 6.2, iOS 8.2)
This is caused when you attempt to call an extension method from a file which is included in the bridging header, but isn't added to the proper target.
To fix this, ensure that the file is a member of the same target as the one that is currently running.
For example, if you are trying to call Objective-C code (e.g. UIColor+Utils.m) from your WatchKit Extension, then the .m file (e.g. UIColor+Utils.m) must have the WatchKit Extension in its Target Membership section.
For more information, see below.
If you include the .h file in the Bridging-Header.h file, but forget to add the file to the target, you will get the following behavior.
If you attempt to call a method on your own class (e.g. ABCClass.doSomething()):
You will get code completion.
You will get a build error: Undefined symbols for architecture x86_64.
If you attempt to call a class extension method (e.g. UIColor.doSomething()):
You will get code completion.
You will NOT get any build errors/warnings.
When attempting to execute that line, you will get a crash: unrecognized selector sent to class.
With xCode 8, when you add a file, make sure you choose the correct target from 'options'. I was choosing a folder and adding it directly to my project but somehow that was not setting the correct target.

Resources