Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions src/messageui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,67 @@ enum MFMailComposeControllerDeferredAction : long {
AddMissingRecipients,
}

/// <summary>Represents the contents of an email draft.</summary>
[NoTV, NoMac, iOS (27, 0), MacCatalyst (27, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor] // init leaves the non-null properties uninitialized
interface MFMailDraft {
/// <summary>Gets the sender address, or <see langword="null" /> if the draft does not specify one.</summary>
[NullAllowed, Export ("from")]
string From { get; }

/// <summary>Gets the subject.</summary>
[Export ("subject")]
string Subject { get; }

/// <summary>Gets the attributed message body.</summary>
[Export ("body")]
NSAttributedString Body { get; }

/// <summary>Gets the primary recipient addresses.</summary>
[Export ("to")]
string [] To { get; }

/// <summary>Gets the carbon-copy recipient addresses.</summary>
[Export ("cc")]
string [] Cc { get; }

/// <param name="subject">The subject.</param>
/// <param name="body">The attributed message body.</param>
/// <param name="from">The sender address.</param>
/// <param name="to">The primary recipient addresses.</param>
/// <param name="cc">The carbon-copy recipient addresses.</param>
/// <summary>Creates an email draft with the specified contents and recipients.</summary>
[Export ("initWithSubject:body:from:to:cc:")]
NativeHandle Constructor (string subject, NSAttributedString body, string from, string [] to, string [] cc);
}

interface IMFComposeAssistantViewControllerDelegate { }

/// <summary>Methods for receiving email drafts from a compose assistant.</summary>
[NoTV, NoMac, iOS (27, 0), MacCatalyst (27, 0)]
[Protocol (BackwardsCompatibleCodeGeneration = false), Model]
[BaseType (typeof (NSObject))]
interface MFComposeAssistantViewControllerDelegate {
/// <param name="controller">The compose assistant that created the draft.</param>
/// <param name="draft">The email draft.</param>
/// <summary>Notifies the delegate that the compose assistant created an email draft.</summary>
[Abstract]
[Export ("composeAssistantViewController:didComposeDraft:")]
void DidComposeDraft (MFComposeAssistantViewController controller, MFMailDraft draft);
}

/// <summary>Provides an interface for composing an email draft.</summary>
[NoTV, NoMac, iOS (27, 0), MacCatalyst (27, 0)]
[BaseType (typeof (UIViewController))]
[PrivateDefaultCtor] // init and initWithCoder: abort at runtime

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just [DisableDefaultCtor]?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[DisableDefaultCtor] only suppresses the generated parameterless init. Because UIViewController conforms to NSCoding, bgen separately emits .ctor(NSCoder) and leaves it public under [DisableDefaultCtor]. On the Xcode 27 Beta 3 runtime, both initWithCoder: and initWithNibName:bundle: unconditionally trap; only initWithDelegate: works. [PrivateDefaultCtor] is intentional so the generated init and .ctor(NSCoder) stay non-public, while the narrow introspection match avoids re-exposing the trapping nib initializer. I verified this against the generated iOS/Mac Catalyst sources and the Beta 3 runtime implementation. There is no separate bgen attribute to suppress only the NSCoder constructor.

interface MFComposeAssistantViewController {
/// <param name="delegate">The object that receives the composed draft.</param>
/// <summary>Creates a compose assistant with the specified delegate.</summary>
[Export ("initWithDelegate:")]
NativeHandle Constructor (IMFComposeAssistantViewControllerDelegate @delegate);
}

/// <summary>Provides a user interface for composing and sending email messages.</summary>
///
/// <related type="externalDocumentation" href="https://developer.apple.com/library/ios/documentation/MessageUI/Reference/MFMailComposeViewController_class/index.html">Apple documentation for <c>MFMailComposeViewController</c></related>
Expand Down
5 changes: 5 additions & 0 deletions tests/introspection/ApiCtorInitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ protected virtual bool Match (ConstructorInfo ctor, Type type)
if (ctor.ToString () == $"Void .ctor(Metal.IMTLDevice, MetalPerformanceShaders.MPSNDArrayDescriptor)")
return true;
break;
case "MFComposeAssistantViewController":
// The inherited UIViewController initializer aborts, and the header does not designate initWithDelegate:.
if (cstr == $"Void .ctor(System.String, Foundation.NSBundle)")
return true;
break;
case "MFMailComposeViewController": // You are meant to use the system provided one
case "MFMessageComposeViewController": // You are meant to use the system provided one
case "GKFriendRequestComposeViewController": // You are meant to use the system provided one
Expand Down

This file was deleted.

10 changes: 0 additions & 10 deletions tests/xtro-sharpie/api-annotations-dotnet/iOS-MessageUI.todo

This file was deleted.

Loading