Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QuickLook] Update bindings for Xcode 13.0 beta 1,2,3,4 #12337

Merged
merged 5 commits into from
Aug 6, 2021
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
6 changes: 5 additions & 1 deletion src/generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1727,7 +1727,11 @@ public TrampolineInfo MakeTrampoline (Type t)
convert.Append ($"var {refname} = Runtime.GetINativeObject<{RenderType (nt)}> ({safe_name}, false);");
pars.Append ($"ref IntPtr {safe_name}");
postConvert.Append ($"{safe_name} = {refname} is null ? IntPtr.Zero : {refname}.Handle;");
invoke.Append ($"ref {refname}");
if (pi.IsOut)
invoke.Append ("out ");
else
invoke.Append ("ref ");
invoke.Append (refname);
continue;
}
} else if (IsNativeEnum (pi.ParameterType)) {
Expand Down
88 changes: 88 additions & 0 deletions src/quicklook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#endif
using System;
using System.ComponentModel;
using UniformTypeIdentifiers;

namespace QuickLook {
#if !MONOMAC
Expand Down Expand Up @@ -170,6 +171,89 @@ interface QLPreviewItem {
#endif
}

delegate bool QLPreviewReplyDrawingHandler (CGContext context, QLPreviewReply reply, out NSError error);
delegate NSData QLPreviewReplyDataCreationHandler (QLPreviewReply reply, out NSError error);
delegate CGPDFDocument QLPreviewReplyUIDocumentCreationHandler (QLPreviewReply reply, out NSError error);

[NoWatch, NoTV, Mac (12,0), iOS (15,0), MacCatalyst (15,0)]
[BaseType (typeof(NSObject))]
interface QLPreviewReply
{
[Export ("stringEncoding")]
nuint StringEncoding { get; set; }

[Export ("attachments", ArgumentSemantic.Copy)]
NSDictionary<NSString, QLPreviewReplyAttachment> Attachments { get; set; }

[Export ("title")]
string Title { get; set; }

[Export ("initWithContextSize:isBitmap:drawingBlock:")]
IntPtr Constructor (CGSize contextSize, bool isBitmap, QLPreviewReplyDrawingHandler drawingHandler);

[Export ("initWithFileURL:")]
IntPtr Constructor (NSUrl fileUrl);

[Export ("initWithDataOfContentType:contentSize:dataCreationBlock:")]
IntPtr Constructor (UTType contentType, CGSize contentSize, QLPreviewReplyDataCreationHandler dataCreationHandler);

// QLPreviewReply_UI
[Export ("initForPDFWithPageSize:documentCreationBlock:")]
IntPtr Constructor (CGSize defaultPageSize, QLPreviewReplyUIDocumentCreationHandler documentCreationHandler);
}

[NoWatch, NoTV, Mac (12,0), iOS (15,0), MacCatalyst (15,0)]
[BaseType (typeof(NSObject))]
interface QLPreviewReplyAttachment
{
[Export ("data")]
NSData Data { get; }

[Export ("contentType")]
UTType ContentType { get; }

[Export ("initWithData:contentType:")]
IntPtr Constructor (NSData data, UTType contentType);
}

[NoWatch, NoTV, Mac (12,0), iOS (15,0), MacCatalyst (15,0)]
[BaseType (typeof(NSObject))]
spouliot marked this conversation as resolved.
Show resolved Hide resolved
interface QLFilePreviewRequest
{
[Export ("fileURL")]
NSUrl FileUrl { get; }
}

[NoWatch, NoTV, Mac (12,0), iOS (15,0), MacCatalyst (15,0)]
[DisableDefaultCtor]
[BaseType (typeof(NSObject))]
interface QLPreviewProvider : NSExtensionRequestHandling
{
}

[NoWatch][NoTV][NoMac] // availability not mentioned in the header files
[iOS (15,0), MacCatalyst (15,0)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Mac ?

without a [Mac] it means the oldest supported (10,9) has it available.

Same for watchOS and tvOS. You likely want [NoWatch, NoTV, NoMac] if it's not available on macOS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if there's no indication on the diffs, xtro, web docs, or header files - I tend to leave the availability of unmentioned platforms as is. But is it best to assume that there is no availability on those platforms? Since it's a breaking change to remove things, and it's always easier to introduce things later on?

Copy link
Contributor

Choose a reason for hiding this comment

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

But is it best to assume that there is no availability on those platforms?

No. Lack of availability attributes means it's been available since our earliest supported versions.
E.g. lack of [NoWatch] implies it's [Watch (2,0)] and that the API has been available in the past 6 years (or so)

This is almost always wrong when adding bindings for a new Xcode (unless it added a new platform).

Since it's a breaking change to remove things, and it's always easier to introduce things later on?

True :-) However it's true for code that we ship (post generation), not the binding sources!

Example: [NoWatch] -> means we're not generating the API on watchOS.

If you don't add [NoWatch] (in binding sources) then the API will be present inside Xamarin.WatchOS.dll (and assumed to be available since 2.0 which is watchOS minimum supported version).

If you want to fix that later, by adding [NoWatch], then you are creating a breaking change (since the API won't be part of Xamarin.WatchOS.dll in the next release).

Copy link
Contributor Author

@rachelkang rachelkang Aug 5, 2021

Choose a reason for hiding this comment

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

Ah, I think my question was a bit confusing! I understand what you explained about the lack of availability attributes in our code - I meant instead to ask about how we should interpret the lack of mention of platform availability in diffs, xtro, web docs, and header files.

So in this case, there is no Watch availability or unavailability mentioned whatsoever in the diffs, xtro, web docs, or header files for this API. So I was asking if that means it's best to assume there's no watch availability and tag as [NoWatch] - does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

Short answer: Whenever in doubt it's better to assume [No*] if availability is not mentioned because it means no code will be generated (and it won't be a breaking change to add it later).

When you add (or modify) sharpie's output then it's good to add comments (for reviewers and people who will update the bindings... years later), e.g.

[NoWatch][NoTV][NoMac] // availability not mentioned in the header files

Long answer

  • Apple's macro are often incomplete or incorrect (e.g. wrong version)
    • Some (not all) gets fixed in newer betas or the next Xcode...
  • There are assumptions like
    • old (pre 9.0) iOS API are assumed to be available on tvOS 9 (first version) unless decorated otherwise
    • old (pre 13) iOS API are assumed to be available on MacCatalyst 13 (first version) ...
    • enums are not always decorated since they are not API (you can see which API uses them to know which attributes are needed)
  • Intro (runtime) and xtro (build time) will spot many, but not all, errors
  • over time you get to know the API/framework and can identify things that looks unusual (and add tests to confirm your gut feelings)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

perfect, thank you!!!

[BaseType (typeof(NSObject))]
interface QLPreviewSceneOptions
{
[Export ("initialPreviewIndex")]
nint InitialPreviewIndex { get; set; }
}

// TODO: BaseType UIWindowSceneActivationConfiguration must first be implemented in UIKit
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[QuickLook] QLPreviewSceneActivationConfiguration not yet bound in Xcode13 because base type UIWindowSceneActivationConfiguration is not yet bound in UIKit

// [iOS (15,0), MacCatalyst (15,0)]
// [BaseType (typeof(UIWindowSceneActivationConfiguration))]
// interface QLPreviewSceneActivationConfiguration
// {
// [Export ("initWithItemsAtURLs:options:")]
// [DesignatedInitializer]
// IntPtr Constructor (NSUrl[] urls, [NullAllowed] QLPreviewSceneOptions options);

// [Export ("initWithUserActivity:")]
// [DesignatedInitializer]
// IntPtr Constructor (NSUserActivity userActivity);
// }

[iOS (11,0)]
[Protocol]
interface QLPreviewingController {
Expand All @@ -178,6 +262,10 @@ interface QLPreviewingController {

[Export ("preparePreviewOfFileAtURL:completionHandler:")]
void PreparePreviewOfFile (NSUrl url, Action<NSError> handler);

[iOS (15,0), Mac (12,0), MacCatalyst (15,0)]
[Export ("providePreviewForFileRequest:completionHandler:")]
void ProvidePreview (QLFilePreviewRequest request, Action<QLPreviewReply, NSError> handler);
}
#else
[Static]
Expand Down
4 changes: 4 additions & 0 deletions tests/introspection/iOS/iOSApiProtocolTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ protected override bool Skip (Type type, string protocolName)
case "NSMergePolicy":
case "SFSafariViewControllerPrewarmingToken": // conformance not in headers
case "SRTextInputSession": // conformance not in headers
case "QLPreviewReply": // conformance not in headers
case "QLPreviewReplyAttachment": // conformance not in headers
return true;
}
break;
Expand Down Expand Up @@ -685,6 +687,8 @@ protected override bool Skip (Type type, string protocolName)
case "NSMergePolicy":
case "SFSafariViewControllerPrewarmingToken": // conformance not in headers
case "SRTextInputSession": // conformance not in headers
case "QLPreviewReply": // conformance not in headers
case "QLPreviewReplyAttachment": // conformance not in headers
return true;
}
break;
Expand Down
23 changes: 0 additions & 23 deletions tests/xtro-sharpie/MacCatalyst-QuickLook.todo
Original file line number Diff line number Diff line change
@@ -1,27 +1,4 @@
!extra-null-allowed! 'CoreGraphics.CGRect QuickLook.QLPreviewControllerDelegate::FrameForPreviewItem(QuickLook.QLPreviewController,QuickLook.IQLPreviewItem,UIKit.UIView&)' has a extraneous [NullAllowed] on parameter #2
!incorrect-protocol-member! QLPreviewItem::previewItemTitle is OPTIONAL and should NOT be abstract
## appended from unclassified file
!missing-protocol-member! QLPreviewingController::providePreviewForFileRequest:completionHandler: not found
!missing-selector! QLFilePreviewRequest::fileURL not bound
!missing-selector! QLPreviewReply::attachments not bound
!missing-selector! QLPreviewReply::initForPDFWithPageSize:documentCreationBlock: not bound
!missing-selector! QLPreviewReply::initWithContextSize:isBitmap:drawingBlock: not bound
!missing-selector! QLPreviewReply::initWithDataOfContentType:contentSize:dataCreationBlock: not bound
!missing-selector! QLPreviewReply::initWithFileURL: not bound
!missing-selector! QLPreviewReply::setAttachments: not bound
!missing-selector! QLPreviewReply::setStringEncoding: not bound
!missing-selector! QLPreviewReply::setTitle: not bound
!missing-selector! QLPreviewReply::stringEncoding not bound
!missing-selector! QLPreviewReply::title not bound
!missing-selector! QLPreviewReplyAttachment::contentType not bound
!missing-selector! QLPreviewReplyAttachment::data not bound
!missing-selector! QLPreviewReplyAttachment::initWithData:contentType: not bound
!missing-type! QLFilePreviewRequest not bound
!missing-type! QLPreviewProvider not bound
!missing-type! QLPreviewReply not bound
!missing-type! QLPreviewReplyAttachment not bound
!missing-selector! QLPreviewSceneActivationConfiguration::initWithItemsAtURLs:options: not bound
!missing-selector! QLPreviewSceneOptions::initialPreviewIndex not bound
!missing-selector! QLPreviewSceneOptions::setInitialPreviewIndex: not bound
!missing-type! QLPreviewSceneActivationConfiguration not bound
!missing-type! QLPreviewSceneOptions not bound
22 changes: 0 additions & 22 deletions tests/xtro-sharpie/iOS-QuickLook.todo
Original file line number Diff line number Diff line change
@@ -1,24 +1,2 @@
!missing-protocol-member! QLPreviewingController::providePreviewForFileRequest:completionHandler: not found
!missing-selector! QLFilePreviewRequest::fileURL not bound
!missing-selector! QLPreviewReply::attachments not bound
!missing-selector! QLPreviewReply::initForPDFWithPageSize:documentCreationBlock: not bound
!missing-selector! QLPreviewReply::initWithContextSize:isBitmap:drawingBlock: not bound
!missing-selector! QLPreviewReply::initWithDataOfContentType:contentSize:dataCreationBlock: not bound
!missing-selector! QLPreviewReply::initWithFileURL: not bound
!missing-selector! QLPreviewReply::setAttachments: not bound
!missing-selector! QLPreviewReply::setStringEncoding: not bound
!missing-selector! QLPreviewReply::setTitle: not bound
!missing-selector! QLPreviewReply::stringEncoding not bound
!missing-selector! QLPreviewReply::title not bound
!missing-selector! QLPreviewReplyAttachment::contentType not bound
!missing-selector! QLPreviewReplyAttachment::data not bound
!missing-selector! QLPreviewReplyAttachment::initWithData:contentType: not bound
!missing-type! QLFilePreviewRequest not bound
!missing-type! QLPreviewProvider not bound
!missing-type! QLPreviewReply not bound
!missing-type! QLPreviewReplyAttachment not bound
!missing-selector! QLPreviewSceneActivationConfiguration::initWithItemsAtURLs:options: not bound
!missing-selector! QLPreviewSceneOptions::initialPreviewIndex not bound
!missing-selector! QLPreviewSceneOptions::setInitialPreviewIndex: not bound
!missing-type! QLPreviewSceneActivationConfiguration not bound
!missing-type! QLPreviewSceneOptions not bound