It turns out `setDepthClipMode` was removed in Xcode 8, so this needs
some manual code to maintain binary compatibility
references:
!extra-protocol-member! unexpected selector MTLRenderCommandEncoder::setDepthClipMode: found
!unknown-native-enum! MTLPrimitiveTopologyClass bound
Native code can provide the same native method for blocks
with different managed signatures, so it's not enough
to hash by method address, we need to take the target type
of the delegate into account as well.
https://bugzilla.xamarin.com/show_bug.cgi?id=34513
The real fix for bug #43658 is in mono master, but the current
version of mono master doesn't build for us, so implement this
workaround instead.
The problem is that the linker doesn't preserve fields of nested types marked
in xml descriptions unless the declaring type is marked. So the workaround
(until we can bump mono) is to mark the declaring type.
https://bugzilla.xamarin.com/show_bug.cgi?id=43658
No news from Apple on the original rdar but the issue was fixed in Xcode
8 beta 6 (and likely earlier betas)
> MP_EXTERN_CLASS_AVAILABLE(3_0)
> @interface MPMediaItemArtwork : NSObject
which makes it possible to enable the type (as it does nor depend on
other, unavailable, types).
references:
* rdar://24982126
* https://trello.com/c/2gxuFbeS
It's the only one, so it's kind of designated, but it's not marked as
such in the header files and it's better matching them (xtro test wise)
reference:
!extra-designated-initializer! MPSMatrixMultiplication::initWithDevice:transposeLeft:transposeRight:resultRows:resultColumns:interiorColumns:alpha:beta: is incorrectly decorated with an [DesignatedInitializer] attribute
reference:
!missing-designated-initializer! SFSafariViewController::initWithURL:entersReaderIfAvailable: is missing an [DesignatedInitializer] attribute
Some types were removed in tvOS 10, including:
!unknown-protocol! AVAssetDownloadDelegate bound
!unknown-type! AVAssetDownloadTask bound
!unknown-type! AVAssetDownloadURLSession bound
!unknown-type! AVAudioInputNode bound
and we're replacing them with stubs so our binaries won't contain any of
the selectors that could be rejected by Apple on the app store
Some (new) fields are also not part of tvOS (and were not in iOS either)
!unknown-field! AVVideoCodecAppleProRes422 bound
!unknown-field! AVVideoCodecAppleProRes4444 bound
!unknown-field! AVVideoColorPrimaries_EBU_3213 bound
!unknown-field! AVVideoTransferFunction_SMPTE_240M_1995 bound
!unknown-field! AVVideoYCbCrMatrix_SMPTE_240M_1995 bound
* [tests][xtro] Many categories are not marked as not available on tvOS, even if the type being extended is not available. This adds entries for them so only missing AV* API remains in tvos.unclassified
Native code can provide the same native method for blocks
with different managed signatures, so it's not enough
to hash by method address, we need to take the target type
of the delegate into account as well.
https://bugzilla.xamarin.com/show_bug.cgi?id=34513
In bug #43592 the following occurs:
* App calls an API that takes a block.
* We create a stack-based ObjC block based on the delegate the app provided.
This block has a pointer to a block description, describing the block
in question (including the signature of the block, as an ObjC-type
encoded string). We allocate a new block description for every block.
* Apple's API stores the pointer to the signature string somewhere.
* Apple calls _Block_copy to get a heap-based block.
* We create a heap-based block, and copy the entire description into the
new heap-based block (including a copy of the signature).
* Apple returns from the API, and then we free the stack-based block
(and the descriptor, and thus the signature string in the descriptor).
* Apple uses the pointer to the signature stored previously to investigate
the signature of the block, and crashes because this signature has been
freed.
The assumption in Apple's code is that the description will never be freed,
which is true for any Xcode project (clang will always be able to create the
block description at compile-time and emit it in the binary, which means the
memory will never be freed). We could potentially do the same thing in the
static registrar, but we'd still need a solution when using the dynamic
registrar.
To fix this instead of copying the entire description structure when creating
a heap-based block from the stack-based block, we make the description ref-
counted, and just use the same description in the heap-based block.
The signature will now stay in memory until both the heap-based and stack-
based blocks have been freed, and we hope Apple doesn't have any API that
needs the signature after all the blocks for that signature have been freed.
https://bugzilla.xamarin.com/show_bug.cgi?id=43592
CALayerDelegate was an informal protocol in earlier versions
of iOS, but elevated to protocol in iOS 10 [1]. Unfortunately this causes
problems with the static registrar, since it needs to know if a protocol
is informal or not to generate the right code, but there's no way
with the current set of attributes we have to express the fact that
CALayerDelegate was an informal protocol until iOS 10, so the static
registrar don't know to treat it correctly when building with earlier
SDKs.
This is the error that results when using CALayerDelegate with an earlier SDK:
/work/monotouch-samples/ZoomingPdfViewer/obj/iPhone/Debug/mtouch-cache/registrar.m:1336:51: error: no type or protocol named 'CALayerDelegate'
@interface ZoomingPdfViewer_TiledPdfView : UIView<CALayerDelegate> {
^
So we temporarily revert the change to make CALayerDelegate formal,
until we have enough metadata for the static registrar to do the
right thing (which is filed as bug #43780 [2])
[1] https://github.com/xamarin/xamarin-macios/commit/0178aa04
[2] https://bugzilla.xamarin.com/show_bug.cgi?id=43780https://bugzilla.xamarin.com/show_bug.cgi?id=43585
The P/Invoke callback method that's called by native code
has a simpler function signature than what the user delegate
has.
Example P/Invoke callback signature:
static unsafe void Invoke (IntPtr block, IntPtr obj)
which ends up calling this delegate:
System.Action<NSDictionary>
The NSDictionary parameter has been simplifed to just IntPtr.
The problem is that we need to encode the block signature according
to the signature of the user delegate (Apple uses the signature
in some cases, and fails/aborts if the signature doesn't match
what the code expects).
So add more metadata to make it possible to find the signature
of the user delegate at runtime.
The generator generates code like this:
block_scheduledCompletion.SetupBlock (Trampolines.SDActionArity1V2.Handler, scheduledCompletion);
where SDActionArity1V2.Handler is defined as this:
static internal readonly DActionArity1V2 Handler = Invoke;
this means we can get the type of `Trampolines.SDActionArity1V2.Handler` at runtime
(which would be `DActionArity1V2` in this case), so put a new attribute (`UserDelegateTypeAttribute`)
at that type:
[UnmanagedFunctionPointerAttribute (CallingConvention.Cdecl)]
[UserDelegateType (typeof (global::System.Action<NSDictionary>))]
internal delegate void DActionArity1V2 (IntPtr block, IntPtr obj);
Then at runtime we check if the target delegate's type has this attribute,
and then we use the type specified by this new attribute instead when
computing the ObjC signature of the block.
https://bugzilla.xamarin.com/show_bug.cgi?id=43592