I have an existing Objective-C app and have developed a SwiftUI iOS 14 Widget for it. So far so good. Now I am trying to reload the timeline from my Objective-C app. I understand that there are no Objective-C api for accessing WidgetCenter, so I have implemented the bridging steps outlined in Apple's documentation (at least I think I have since I am totally new to Swift). I cannot seem to be able to get Widget Center nor WidgetCenter.shared.reloadAllTimelines()recognized in my Objective-C app. I have tried many approaches with no success, so I must be doing something wrong. Any help or suggestions would be greatly appreciated.
I faced with the same issue. The solution for this was to create a swift file for example: WidgetKitHelper. Create the assigned swift-objc header with that too (bridging header file) if it not generated automatically you can add it by manually (search for it).
In the helper object you can get access to widgetkit, and if you do the rest to be able to see the swift code from your objc code, you can use this as a wrapper.
Tips:
import WidgetKit
#available(iOS 14.0, *)
#objcMembers final class WidgetKitHelper: NSObject {
class func reloadAllWidgets(){
#if arch(arm64) || arch(i386) || arch(x86_64)
WidgetCenter.shared.reloadAllTimelines()
#endif
}
}
obj-c code:
First import the swift code by adding:
#import "YourProjectName-Swift.h"
Then you can use:
[WidgetKitHelper reloadAllWidgets];
Related
so I have an SDK written in swift that overrides WKWebView delegation to check SSL certificates/security measure.
and I want to use it on my Objective-C project :
The delegation works as intended, but when try to execute didFailNavigation, it crashes... but when I try to use it on a swift project, it works perfectly. do you guys know why this happening in objective-c?
And one more question, in swift I can do the like this
self.webView?.navigationDelegate = safeWebDelegate.wkWebDelegate as? WKNavigationDelegate
but in iOS I cannot do :
self.webView.navigationDelegate = (WKNavigationDelegate *)safeWebDelegate.wkWebDelegate;
it says that WKNavigationDelegate not found. Is there any workaround on this? Thanks
I am working in a mixed ObjC Swift project. I am currently overriding functions that where written in ObjC in a swift subclass. I'm wondering if there is a quick way to view the auto generated Swift header files for the objC file so that I can check the syntax of functions after they have been converted to swift.
I'm wondering if there is a quick way to view the auto generated Swift header files for the objC
Switch to the Generated Interface in the first menu of the jump bar.
Example: before:
after:
When you add a Swift file to an Objective-C project, Xcode will generate a Swift-to-ObjC header, as described here: http://ericasadun.com/2014/08/21/swift-calling-swift-functions-from-objective-c/
Without this header it is not possible to call Swift code from Objc-C. However Xcode is not auto-generating this header for my framework target.
If I create an Objective-C app and drop a Swift file into it, then it does auto-generate one, so I suspect it's because I'm building a framework and not an app. Without one its not possible to use the Swift code from the Obj-C code.
I tried using the one which was generated for the app (after renaming it and putting it in the appropriate DerivedData folder ) but Xcode didn't update it and actually it will eventually delete it, so manually creating or trying to maintain this file is not feasible.
How can I make Xcode generate this header for a framework target, so that I can call my Swift code from my Obj-C code?
And remember folks: the question is about calling Swift from Obj-C not calling Obj-C from Swift.
I created a new Framework project, added both Obj-C and Swift files, and was able to do this:
// MyObjCClass.m
#import "MyObjCClass.h"
#import <MyFramework/MyFramework-Swift.h>
#implementation MyObjCClass
- (void)test {
[[MySwiftClass alloc] init];
}
#end
Note that your Swift class must be public:
public class MySwiftClass: NSObject {
// ...
}
More information is available in Apple's Swift/Obj-C interop documentation under "Importing Swift into Objective-C".
I've been trying to checkout CocoaPods new framework setup to get some Pods going and I'm having trouble using the Swift one's in my Objective-C project.
First things first, this is CocoaPods prerelease 0.35, you can read about how to use and install it here.
Here's my current Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'MBProgressHUD'
pod 'SLPagingViewSwift'
MBProgressHUD is a common spinning indicator, and SLPagingViewSwift is a random project I found by typing Swift into the cocoapods search. Here's the ViewController.m In my project:
#import "ViewController.h"
#import SLPagingViewSwift;
#import MBProgressHUD;
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Works just fine
MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:hud];
[hud show:YES];
// Causes Error -- Won't build
SLPagingViewSwift *sl = [[SLPagingViewSwift alloc] init];
}
#end
Here's the SLPagingViewSwift declaration:
class SLPagingViewSwift: UIViewController, UIScrollViewDelegate {
As you can see, it inherits from UIViewController, so it shouldn't be a problem to just allocate it and initialize it. If I add the file separately as just a file, the above code runs just fine. I know it works.
tl;dr
How can I use a pure Swift Framework created by CocoaPods in a pure Objective-C class?
TroubleShooting
Mostly I've been trying various imports. Apple recommends the #import style here
But I have been trying multiple other varieties:
// Compiler Error
#import <SLPagingViewSwift/SLPagingViewSwift.h>
// Builds Fine -- Doesn't Work
#import <SLPagingViewSwift/SLPagingViewSwift-Swift.h>
#import "SLPagingViewSwift-Swift.h"
I've also been trying a few other Swift libraries from time to time to see if I could make anything click.
I don't see anything on the Cocoapods issues that can help this, I also didn't find anything in their blog / release stuff.
Note
If I add the SLPagingViewSwift.swift file separately to the project the old fashioned way, it works just fine.
I think you have to declare the swift class as public, otherwise it is treated as an internal class and can be only be seen within the same module, and this could be the reason why adding it to the same project as files work, but as a framework doesn't. Other thing that occurs to me is that the framework may need to add #objc in front of the class declaration so that it can be seen within objective-c classes. Also reading Apple's guide of Mix and Match between objective c and swift it says that when you import an external framework, you need to make sure the Defines Module build setting for the framework you’re importing is set to Yes. Have you checked with any of those options?
Jus use the
#import SwiftModuleName;
Syntax, and make sure the functions you want to use are public (and #objc)
In my case there was no “use_frameworks!” into podfile (old project).
I added it and then I was able to use import like that
#import "PODNAME-Swift.h"
and use classes from pod.
But finally I wasn't able to use that swift pod, because of lack objective c exposition. I believe this will be the issue in many cases.
I'm building a game with cocos2d (for iPad) and I would like to know if a class exists, in objective-c or cocos2d that allows me to import another class (written in objective-c).
During the game-session, this has to be compiled in a dynamic way and the methods of this class have to be used in the game to implement it.
I've found the NSBundle of objective-c but they can't be used in this way for iPad.
Can you give me some advice, If you know a solution with cocos2d or library of objective-c?
if there is no solution a parser may be possible?
Sorry to answer your questions so late.. I hope this helps..
lets say you want to check if the class 'ADBannerView' is available. Then you can do something like this.
Class classAdBannerView = NSClassFromString(#"ADBannerView");
if (classAdBannerView != nil){
//the class is available.
}