Can we share msmessage without develop an imessage extension? - ios10

I saw there is message property in MFMessageComposeViewController. Can we construct an MSMessage and assign it to MFMessageComposeViewController, then share this message in new iMessage App without developing an extension? If we can do that, we can share other with a message with images and title, instead of just plain string or attachment before iOS 10.

From what I learn here https://forums.developer.apple.com/thread/49922, you need to create an imessage extension target (you don't need to do any develop for the target) , then you can share the msmessage in MFMessageComposeViewController
This is the demo in the link above:
Create a brand new Single-View Application
In main.storyboard, create a button in the middle of the screen
Ctrl-drag "Touch Up Inside" for the button to my ViewController class to create onTouchUp in code (see below)
Wrote the code below
import UIKit
import Messages
import MessageUI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func onTouchUp(_ sender: AnyObject) {
let composeVC = MFMessageComposeViewController()
let msgLayout = MSMessageTemplateLayout()
msgLayout.caption = "something here"
let message = MSMessage()
message.layout = msgLayout
composeVC.message = message
self.present(composeVC, animated: true, completion: nil)
}
}
Create a Target of a MessagesExtension
Run the app on iPhone 6s Plus
See the MSMessage in the MFMessageComposeViewController

Related

Unknown class QuoteDetailViewController in Interface Builder file with Xcode 12

I saw a lot of posts about this error in Xcode but all of them are quite old. I'm learning how to code in Swift and I'm following the instruction of book.
My Xcode is version 12.5.1. The goal of this app is to display a list of quotes (string) and when I tap on one of them, display a new view that has as a title the quote.
I have a very simple storyboard. There is a TableView with a segue to a View. I created a new Cocoa file for tableview. TableView is working.
I connect the TableView with the View.
I repeated the some process for the View. I added a new Cocoa file called QuoteDetailViewController, click on top of the view and in the Class I selected from the list the file.
When I run the application in the iPhone 11 simulator, the view doesn't have any quote as title. I put a breakpoint in the code connected to the TableView and the app stops there. If I put a breakpoint in the QuoteDetailViewController nothing happens but I see an error in the output
2021-08-11 19:13:17.215204+0100 QuoteApp[80238:4055489] [Storyboard] Unknown class QuoteDetailViewController in Interface Builder file.
The QuoteDetailViewController is very basic.
import UIKit
class QuoteDetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let quoteViewController = segue.destination as? QuoteDetailViewController {
if let selectedQuote = sender as? String {
quoteViewController.title = selectedQuote
}
}
}
}
I tried to build again and again the app. I tried to Clean Build Folder and build again. I tried to recreate the View and the code. After all of that, nothing changed. The error is still there.
The source code is on GitHub.
Update
If I click on the arrow at the end of Class and just before the dropdown, Xcode opens the file I expect to be opened.
Select the QuoteDetailViewController, open Side Inspector view and Update the Target Membership same as QuoteTableViewController
Select the controller On the Storyboard, and Add it to the module.
Check Screenshots for reference:
So, I said that in the QuoteDetailViewController I have this code.
import UIKit
class QuoteDetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let quoteViewController = segue.destination as? QuoteDetailViewController {
if let selectedQuote = sender as? String {
quoteViewController.title = selectedQuote
}
}
}
}
The error was that the function prepare must be in the QuoteTableViewController.

windowWillClose and button action not called Swift

I'm designing a mac app with Xcode 10 (beta) and I got an issue with the Preference Window Controller
I have in my Main.storyboard a NSWindowController of custom class PreferenceWindowController with a toolbar. Here are its connections :
Here is the full class :
class PreferenceWindowController: NSWindowController, NSWindowDelegate {
#IBAction func didClickAuthor(_ sender: Any) {
print("author")
}
#IBAction func didClickTypo(_ sender: Any) {
print("typo")
}
override func windowDidLoad() {
super.windowDidLoad()
}
func windowWillClose(_ notification: Notification) {
print("willClose")
}
}
The window is initiated via the AppDelegate class with this code :
let storyboard = NSStoryboard(name: "Main",bundle: nil)
if let wc = storyboard.instantiateController(withIdentifier: "PreferenceWindowController") as? PreferenceWindowController
{
wc.showWindow(self)
}
The window opens as expected, with the toolbar clickable, but no functions from PreferenceWindowController are called at all, neither the closing of the window, nor the clicks on the toolbar.
I checked every connections, every class name, and I really don't know what's wrong...
SOLUTION
The solution is to store the PreferenceViewController class inside the AppDelegate class as a variable.
My solution :
var preferenceWindowController:PreferenceWindowController? = nil
#IBAction func clickPreferences(_ sender: Any) {
if let wc = storyboard.instantiateController(withIdentifier: "PreferencesWindowController") as? PreferenceWindowController {
let window = wc.window
preferenceWindowController = wc
wc.showWindow(self)
}
}
Thank you for helping !
The comment above seems like it could be on the right track. Based on the code context you've included in your question, it looks like the window controller you create will only have a lifetime for that function call.
Try making the window controller an instance variable. This is normally how I wire things up in an App delegate that creates window controllers. It's a simple pattern that works well.

Can't create/send iMessage in my extension on any view except the initial view

I'm currently working on an iMessage app which has the users sign in on storyboard view 1 and then allows them to generate/send a message on storyboard view 2. After many attempts, I'm finding that the MSMessage portion of the code just doesn't execute on any view except view 1 - the initial view controller.
I'm sure this is a simple fix but I honestly just can't find out why. Any help would be appreciated.
Message generation/send code:
#IBAction func Testing(_ sender: Any) {
let layout = MSMessageTemplateLayout()
layout.caption = "Hello World"
let message = MSMessage()
message.layout = layout
activeConversation?.insert(message, completionHandler: nil)
}

AppleTV - tvos - Hybrid app using native and TVMLKIT - Can't back to native app

I'm a beginner on TVOS.
I'd like to create an hybrid app on AppleTV using a native app and TVMLKIT.
My native application is just a simple native app with buttons (using swift).
When we click on a button, I launch a a javascript app using TVLMKIT and TVJS.
My TVJS as uses the Player to display a video.
When the video is over, I want to close the TVJS app and back to the native ViewController.
My problem is that when I back to native app, I loose the focus on my native View (the app is frozen).
native ViewController:
import UIKit
import TVMLKit
class ViewController: UIViewController, TVApplicationControllerDelegate {
var window: UIWindow?
var appController: TVApplicationController?
var appControllerContext = TVApplicationControllerContext();
static let TVBaseURL = "http://localhost:9001/"
static let TVBootURL = "\(ViewController.TVBaseURL)/client/js/application.js"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var label: UILabel!
#IBOutlet weak var viewAd: UIView!
#IBAction func clickOnlaunchAd(sender: AnyObject) {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
guard let javaScriptURL = NSURL(string: ViewController.TVBootURL) else {
fatalError("unable to create NSURL")
}
appControllerContext.javaScriptApplicationURL = javaScriptURL
appControllerContext.launchOptions["BASEURL"] = ViewController.TVBaseURL
appController = TVApplicationController(context: appControllerContext, window: window,delegate: self)
}
#IBAction func clickOnChangeText(sender: AnyObject) {
label.text = "changed";
}
func appController(appController: TVApplicationController, didStopWithOptions options: [String : AnyObject]?) {
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
}
func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext){
let notifyEventToNative : #convention(block) (NSString!) -> Void = {
(string : NSString!) -> Void in
print("[log]: \(string)\n")
self.appController?.stop()
}
jsContext.setObject(unsafeBitCast(notifyEventToNative, AnyObject.self), forKeyedSubscript: "notifyEventToNative")
}
}
Just before calling "notifyEventToNative" from my TVJS, I call "navigationDocument.clear();" to clear the TVML view.
I can see my native app but I can't interact with it.
Any ideas?
Thanks.
I also had the same problem. I was opened a TVML document from the UIViewController. And I also lost the focus. So, first of all I can advice you to override var called preferredFocusedView in your ViewController. In this method you can return reference to viewAd. But the better solution would be to wrap your ViewController into the TVML-item (with the TVMLKit framework). In that case I hope that you will have no problems with focus because you will use TVML during the whole application.

Swift-passing global variables to the #IBAction function?

I am trying to allow the user to select a .png file to open by clicking file on the menu bar of the application, and then open a Microsoft Word file in the same way.
The problem is it appears that #IBAction func SelectFileToOpen(sender: NSMenuItem) {} cannot access global variables, or set them, and seems completely independent from the rest of the code
here is my code designed to demonstrate how the method can't read global variables:
//
// AppDelegate.swift
// Swift class based
//
// Created by ethan sanford on 2015-01-16.
// Copyright (c) 2015 ethan D sanford. All rights reserved.
//
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
var myURL=NSURL(fileURLWithPath: "")
#IBAction func btnConcat(sender: NSButton) {
myURL = NSURL(fileURLWithPath: "///Users/ethansanford/Desktop/BigWriting.png")
var say_something = "set URL button clicked"
print(say_something);
print(myURL)
}
#IBAction func SelectFileToOpen(sender: NSMenuItem) {
var say_something = "Menu bar, file-open clicked:"
print(say_something);
print(myURL);
}
#IBAction func communicate(sender: AnyObject) {
var say_something = "communicate button clicked:"
print(say_something);
print(myURL);
}
}
Here is the NSlog produced from this code. Notice that the URL button and the commincate button methods can share the myURL variable, but the file open button seems unable to:
URL button clickedOptional(file://///Users/ethansanford/Desktop/BigWriting.png)
communicate button clicked:Optional(file://///Users/ethansanford/Desktop/BigWriting.png)Menu bar
file-open clicked:nil
communicate button clicked:Optional(file://///Users/ethansanford/Desktop/BigWriting.png)
I need the myURL variable to be able to be used in all three methods. This is necessary for later when I need these methods to communicates so I can take the users selection and display it in an image well. Thanks for any help you can provide. I believe the problem is something specific to the file button in the menu bar.
Can anyone explain to me how to get around this problem?
In your code myURL is an instance variable that will be created within the app delegate. I wonder if you have oversimplified your code sample.
Having said that it should be accessible from the instance methods of the app delegate but having IBAction methods in the AppDelegate rather than in UI code seems like an odd choice (I've never tried it).