Swfit: assgin an Objective C ViewController delete get error: “Type 'xxViewController' does not confirm to protocol” - swift-protocols

I have a "HomeViewController.h" include a container view belongs to "PublishViewController.swift". When i click the button on container view, i want to popup "AddEventViewController.h".
But when i assign "HomeViewController as the delegate of AddEventViewController, i got the error as
"Type 'HomeViewController' does not confirm to
protocol"AddEventViewControllerDelegate"
What did i miss or is this wrong?
Here is my code:
HomeViewController.h
#interface HomeViewController ()
AddEventViewController.h
#protocol AddEventViewControllerDelegate <NSObject>
#end
#interface AddEventViewController : UIViewController
#end
PublishViewController.swift
let addEventVC = self.storyboard?.instantiateViewControllerWithIdentifier("AddEventViewController") as AddEventViewController
if let homeVC = self.parentViewController as? HomeViewController {
addEventVC.delegate = homeVC
}
self.presentViewController(addEventVC, animated: true, completion: nil)
Xcode screenshot:

Related

UNNotificationServiceExtension Not work, even set mutable-contet to 1

i write a app in objective-c. i use oneSignal framework for push notification. but my problem is UNNotificationServiceExtension not run and not work. i need to change the body of notifications before show to the user, and for that i need to this extension, but not worked ..
i set the mutable-content to 1 but still not working !!!
this is my received notification in app :
{
aps = {
alert = {
body = sdf;
subtitle = sdf;
title = sdf;
};
"mutable-content" = 1;
sound = default;
};
custom = {
i = "3a36c1ea-873f-4bac-8bd5-5b4a9eb4fd34";
};
}
and this is my UNNotificationServiceExtension :
#import <OneSignal/OneSignal.h>
#import "NotificationService.h"
#interface NotificationService ()
#property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
#property (nonatomic, strong) UNNotificationRequest *receivedRequest;
#property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
#end
#implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.receivedRequest = request;
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
[OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
// DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is excuting
// Note, this extension only runs when mutable-content is set
// Setting an attachment or action buttons automatically adds this
NSLog(#"Running NotificationServiceExtension");
// self.bestAttemptContent.body = [#"[Modified] " stringByAppendingString:self.bestAttemptContent.body];
self.contentHandler(self.bestAttemptContent);
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
NSLog(#"expired");
[OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
self.contentHandler(self.bestAttemptContent);
}
#end

Bind Method With Delegate

I'm creating a binding library to bind native Objective-C framework.
I have the following delegate which I need to add it's declaration to ApiDefinition file and then I need to implement it using my Xamarin.iOS app:
- (void)Initialize:(id <MMSDKDelegate> _Nullable)pDelegate;
MMSDKDelegate:
#protocol MMSDKDelegate <IMMDelegate>
- (void)Started;
#end
IMMDelegate:
#protocol IMMDelegate
- (void)Inserted;
- (void)Removed;
- (void)ReaderConnected;
- (void)ReaderRemoved;
#end
I need the required definition in ApiDefinition file and I need a sample code to call this method from my Xamarin.iOS app.
Update
The Framework I'm dealing with is communicating with card reader device attached with iPhone to read ID card info, it has methods to be called on reader inserted / removed & card inserted / removed..
I have implemented the answer by #cole-xia, but the issue is the methods inside IMMDelegate are never called when I insert card reader or ID. When I call ReadCardData(), it should call Started() which will display information saved by Inserted(), but the current result is that Started() method is called after calling ReadCardData(), but Inserted() and ReaderConnected() are never called in any stage.
In the demo app of Framework, it is used as the following (and works properly):
// Demo app -> ViewController.m
#interface ViewController () <MMSDKDelegate>
#end
#implementation ViewController {
MMSDK *sdkInstance;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
sdkInstance = [MMSDK SharedInstance];
[sdkInstance Initialize:self];
}
- (void)Started
{
// Update UI by: reading in progress ..
}
- (void)Inserted
{
// Update UI by: card inserted
// And read card data
[self readData:self];
}
- (void)Removed
{
// Update UI by: card removed
}
- (void)ReaderConnected
{
// Update UI by: card reader connected
}
- (void)ReaderRemoved
{
// Update UI by: card reader removed
}
- (IBAction)readData:(id)sender
{
var *data = [sdkInstance ReadCardData:YES pWithSignatureImage:YES pWithAddressData:YES];
if (data.hasError) {
// No data fetched
return;
}
if (data) {
// return card data
}
}
All suggestions are welcome and appreciated.
In summary, I just need to do same functionality of demo app in Xamarin.iOS app.
Use Sharpie to create ApiDefinition
The result on my side :
// #protocol IMMDelegate
[BaseType (typeof (NSObject))]
[Protocol, Model]
interface IMMDelegate
{
// #required -(void)Inserted;
[Abstract]
[Export ("Inserted")]
void Inserted ();
// #required -(void)Removed;
[Abstract]
[Export ("Removed")]
void Removed ();
}
// #protocol MMSDKDelegate <IMMDelegate>
[BaseType (typeof (NSObject))]
[Protocol, Model]
interface MMSDKDelegate : IMMDelegate
{
// #required -(void)Started;
[Abstract]
[Export ("Started")]
void Started ();
}
// #interface ACR : NSObject
[BaseType (typeof(NSObject))]
interface YourClass
{
// -(void)Initialize:(id<MMSDKDelegate> _Nullable)pDelegate;
[Export ("Initialize:")]
void Initialize ([NullAllowed] MMSDKDelegate pDelegate);
}
Usage:
class MyDelegate : MMSDKDelegate {
public void Started()
{
}
public override void Removed()
{
}
public override void Inserted()
{
}
}
//In ViewController
public override void ViewDidLoad()
{
base.ViewDidLoad();
YourClass yourClass = new YourClass();
yourClass.Initialize(new MyDelegate());
}
Along with Cola Xia's answer you may also need to make sure that, such third party device SDK integration requires some entries in the info.plist file's "Supported external accessory protocols" key.
Please check XCode sample and check if there is an entry for the "Supported external accessory protocols" key. If it is there, then you should add them in your Xamarin.iOS project's info.plist file.
I hope this may help!

Why Isn't My Bridged Method Being Called Properly?

I'm creating a bridge from iOS to React Native for HomeKit. I'm currently just getting started and simply trying to create a Home for test purposes. I've successfully accepted permissions for HomeKit as set in the info.plist aka NSHomeKitUsageDescription.
RNHomeKit.m
#import "RNHomeKit.h"
#import <HomeKit/HomeKit.h>
#import <React/RCTLog.h>
#implementation RNHomeKit
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(createHome) {
RCTLog(#"FAKELY CREATING HOME");
HMHomeManager *myHomeManager = [[HMHomeManager alloc] init];
[myHomeManager addHomeWithName: #"Matt's Awesome Home" completionHandler:^(HMHome *home, NSError *error) {
RCTLog(#"REALLYING CREATING HOME");
if (!error) {
RCTLog(#"Created Home : %#",home.name);
} else {
RCTLog(#"Error: %#", error);
}
}];
}
#end
RNHomekit.h
#import <Foundation/Foundation.h>
#import <HomeKit/Homekit.h>
#import <React/RCTBridgeModule.h>
#interface RNHomeKit : NSObject <RCTBridgeModule>
#end
I'm calling my createHome method on my homescreen's componentDidMount() using RNHomeKit.createHome();. FAKELY CREATING HOME is being logged, whereas REALLYING CREATING HOME is never seen. Why am I not hitting the addHomeWithName?
I tried reverse engineering a Native HomeKit example app and made some changes that allowed it to work. An explanation as to why my original implementation didn't work would be great though!
RNHomeKit.h
#import <Foundation/Foundation.h>
#import <HomeKit/Homekit.h>
#import <React/RCTBridgeModule.h>
#interface RNHomeKit : NSObject <RCTBridgeModule, HMHomeManagerDelegate>
#property (strong, nonatomic) HMHomeManager *myHomeManager;
#end
RNHomeKit.m
#import "RNHomeKit.h"
#import <HomeKit/HomeKit.h>
#import <React/RCTLog.h>
#implementation RNHomeKit
#synthesize myHomeManager;
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(createHome) {
RCTLog(#"FAKELY CREATING HOME");
self.myHomeManager = [[HMHomeManager alloc] init];
self.myHomeManager.delegate= self;
[self.myHomeManager addHomeWithName: #"Matt's Awesome Home" completionHandler:^(HMHome *home, NSError *error) {
RCTLog(#"REALLYING CREATING HOME");
if (!error) {
RCTLog(#"Created Home : %#",home.name);
} else {
RCTLog(#"Error: %#", error);
}
}];
}
#end

fetchRequest.predicate with Coredata runs fine with Objective-C but not with swift

I have two entities with relationships in coredata:
Entity "Kategorien" has the relation "To Many" to Entity "Details" that is called "kategorie"
In controllerA with "Kategorien" i pick "Kategorien" and reach it to the controller "DetailViewController" with "Details":
Swift:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "MainDetail" {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()!
let controller = segue.destinationViewController as DetailViewController
let kat:Kategorien = self.fetchedResultsController.objectAtIndexPath(indexPath) as Kategorien
controller.kategorie = kat }
}
In DetailViewController i receive it:
class DetailViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var kategoie:Kategorien!
In Objective-C kat is a property in DetailViewController.h
#property (strong, nonatomic) Kategorien *kat;
and in the fetchResulController i just said
#pragma mark - Fetched results controllers delegates
- (NSFetchedResultsController *)fetchedResultsController {
...
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"kategorie == %#", kat];
and the records for the kategorie are shown.
With Swift in the fetchResulController i tried it with
fetchRequest.predicate = NSPredicate(format:"kategorie == %#", kategorie)
and other ways (i.e. kategorie.description) but
no records will appear
Whar did i missunderstand? Where is my mistake? It drives me crazy...
That constructor is not available in swift, since it uses varargs.
Instead of the Objective C constructor:
+ (NSPredicate *)predicateWithFormat:(NSString *)format
use the swift constructor:
init(format predicateFormat: String,
argumentArray arguments: [AnyObject]?) -> NSPredicate
So your code should look like:
fetchRequest.predicate = NSPredicate(format:"kategorie == %#", argumentArray:[kategorie])
i got it! :-)
Took a solution from Ray Wenderlichs "Core Data by Tutorials" to manage the MOC:
import CoreData
public class CoreDataStack {
let context:NSManagedObjectContext
let psc:NSPersistentStoreCoordinator
let model:NSManagedObjectModel
let store:NSPersistentStore?
...
This class is called by AppDelegate.swift (no MOC...) and the ViewControllers. But this allways creates a new MOC! So "Kategorien" and "Details" have own MOCs.
So the fetchRequest
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"kategorie == %#", kategorie]
in Details has another MOC as kategorien got from controllerA.
Now i killed the class CoreDataStack and ported all to AppDelegate.swift see Swift: cannot preload Coredata. Now all use the same MOC and everything is fine... :-)

Problem with objective c delegate

I've created a custom objective c delegate for my application which opens a preference window, I first init and alloc memory for the pref window class (which contains id <PrefWindowDelegate> delegate;) I then set pref.delegate = self; in my main app controller.
The preference window view controller class has - (void)windowWillClose:(NSNotification *)notification at which time i just use [delegate windowHasClosed]; However it seems that delegate does not point to the same delegate that was set when the pref controller class was init'ed at the time that - (void)windowWillClose gets executed.
How can I fix this?
In the header file for the preference window controller
id <PreferenceWindowDelegate> delegate;
In the implementation file:
- (void)windowWillClose:(NSNotification *)notification {
[delegate windowDidClose];
NSLog(#"Pref window closed");
}
in the app controller:
- (void)PrefWindowClosed {
NSLog(#"Preference window closed");
prefWindowOpen = false;
}
header:
#interface appControllerDelegate : NSObject <NSApplicationDelegate, PreferenceWindowDelegate>
PreferenceWindowViewController *pref2;
[NSBundle loadNibNamed:#"PreferenceWindow" owner:pref2];
prefWindowOpen = true;
- (void)windowDidClose {
prefWindowOpen = false;
}
- (IBAction)openPrefWindow:(id)sender {
if(!isRegistered) {
return;
}
if(pref2 == nil){
pref2 = [[PreferenceWindowViewController alloc] init];
pref2.delegate = self;
[NSBundle loadNibNamed:#"PreferenceWindow" owner:pref2];
prefWindowOpen = true;
}
}
Which is called when the user clicks the "Preference" menu item

Resources