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
39 changes: 22 additions & 17 deletions src/UIKit/UIDragDropSessionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,49 @@

#if !TVOS

// Disable until we get around to enable + fix any issues.
#nullable disable
#nullable enable

namespace UIKit {

/// <summary>Contains methods for working with drag-and-drop sessions, including a default implementation of <see cref="UIKit.IUIDropSession.LoadObjects(ObjCRuntime.Class,System.Action{Foundation.INSItemProviderReading[]})" />.</summary>
/// <remarks>To be added.</remarks>
/// <summary>Contains extension methods for working with drag-and-drop sessions.</summary>
public static class UIDragDropSessionExtensions {

/// <typeparam name="T">To be added.</typeparam>
/// <param name="session">To be added.</param>
/// <param name="completion">To be added.</param>
/// <summary>To be added.</summary>
/// <returns>To be added.</returns>
/// <remarks>To be added.</remarks>
public static NSProgress LoadObjects<T> (this IUIDropSession session, Action<T []> completion) where T : NSObject, INSItemProviderReading
/// <summary>Loads objects of the specified type from the drop session and invokes the completion handler when done.</summary>
/// <typeparam name="T">The type of objects to load from the drop session.</typeparam>
/// <param name="session">The drop session to load objects from.</param>
/// <param name="completion">The completion handler to invoke with the loaded objects.</param>
/// <returns>An <see cref="NSProgress" /> object that can be used to track the loading progress.</returns>
public static NSProgress LoadObjects<T> (this IUIDropSession session, Action<T []?> completion) where T : NSObject, INSItemProviderReading
{
// allowing null for 'completion' doesn't make much sense, but we have tests verifying that it's allowed,
// so make the implementation work with a null 'completion' handler.
ArgumentNullException.ThrowIfNull (session);

return session.LoadObjects (new Class (typeof (T)), (v) => {
var arr = v as T [];
if (arr is null && v is not null) {
arr = new T [v.Length];
for (int i = 0; i < arr.Length; i++) {
if (v [i] is not null)
arr [i] = Runtime.ConstructNSObject<T> (v [i].Handle);
arr [i] = Runtime.ConstructNSObject<T> (v [i].Handle)!;
}
}
GC.KeepAlive (v);

completion (arr);
if (completion is not null)
completion (arr);
});
}

/// <summary>Returns <see langword="true" /> if the specified <paramref name="session" /> can instantiate items of the specified <paramref name="type" />.</summary>
/// <param name="session">The session to query.</param>
/// <param name="type">The type of object to query about.</param>
/// <summary>Returns <see langword="true" /> if the specified <paramref name="session" /> can instantiate items of the specified <paramref name="type" />.</summary>
/// <returns>To be added.</returns>
/// <remarks>To be added.</remarks>
/// <param name="type">The type of object to query about.</param>
/// <returns><see langword="true" /> if the session can load objects of the specified type; otherwise, <see langword="false" />.</returns>
public static bool CanLoadObjects (this IUIDragDropSession session, Type type)
{
ArgumentNullException.ThrowIfNull (session);
ArgumentNullException.ThrowIfNull (type);

return session.CanLoadObjects (new Class (type));
}
}
Expand Down
1 change: 0 additions & 1 deletion tests/cecil-tests/HandleSafety.KnownFailures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ public partial class HandleSafetyTest {
"UIKit.UIAlertView..ctor (System.String, System.String, UIKit.IUIAlertViewDelegate, System.String, System.String[])",
"UIKit.UIAppearance.Equals (System.Object)",
"UIKit.UIContentSizeCategoryExtensions.Compare (UIKit.UIContentSizeCategory, UIKit.UIContentSizeCategory)",
"UIKit.UIDragDropSessionExtensions/<>c__DisplayClass0_0`1.<LoadObjects>b__0 (Foundation.INSItemProviderReading[])",
"UIKit.UIFontFeature.ObjCRuntime.INativeObject.get_Handle ()",
"UIKit.UIPasteboard.set_Images (UIKit.UIImage[])",
"UIKit.UIToolbar.SetItems (UIKit.UIBarButtonItem[], System.Boolean)",
Expand Down
21 changes: 21 additions & 0 deletions tests/monotouch-test/UIKit/UIDragDropSessionExtensionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,30 @@ public void LoadObjectsTest ()
Assert.Ignore ("Ignoring tests: Requires iOS11+");

var test = new DropSession ();
Assert.That (test.CalledCanLoadObjects, Is.False, "CalledCanLoadObjects #1");
test.CanLoadObjects (typeof (UIImage));
Assert.That (test.CalledCanLoadObjects, Is.True, "CalledCanLoadObjects #2");

Assert.That (test.CalledLoadObjects, Is.False, "CalledLoadObjects #1");
test.LoadObjects<UIImage> (null);
Assert.That (test.CalledLoadObjects, Is.True, "CalledLoadObjects #2");

test.CalledLoadObjects = false;
Assert.That (test.CalledLoadObjects, Is.False, "CalledLoadObjects #1");
var calledCallback = false;
test.LoadObjects<UIImage> ((arr) => {
calledCallback = true;
});
Assert.That (calledCallback, Is.True, "calledCallback");
Assert.That (test.CalledLoadObjects, Is.True, "CalledLoadObjects #2");

}
}

class DropSession : NSObject, IUIDropSession {
public bool CalledLoadObjects;
public bool CalledCanLoadObjects;

public IUIDragSession LocalDragSession => throw new NotImplementedException ();

public UIDropSessionProgressIndicatorStyle ProgressIndicatorStyle { get => throw new NotImplementedException (); set => throw new NotImplementedException (); }
Expand All @@ -43,6 +61,7 @@ class DropSession : NSObject, IUIDropSession {

public bool CanLoadObjects (Class itemProviderReadingClass)
{
CalledCanLoadObjects = true;
Assert.That (itemProviderReadingClass.Handle, Is.EqualTo (new Class (typeof (UIImage)).Handle), "UIDragDropSessionExtensionsTest did not convert the type properly for 'CanLoadObjects'.");
return true;
}
Expand All @@ -54,7 +73,9 @@ public bool HasConformingItems (string [] typeIdentifiers)

public NSProgress LoadObjects (Class itemProviderReadingClass, Action<INSItemProviderReading []> completion)
{
CalledLoadObjects = true;
Assert.That (itemProviderReadingClass.Handle, Is.EqualTo (new Class (typeof (UIImage)).Handle), "UIDragDropSessionExtensionsTest did not convert the type properly for 'LoadObjects'.");
completion (Array.Empty<INSItemProviderReading> ());
return new NSProgress ();
}

Expand Down