How to pass collection type parameter to swift-winrt projected winui API?

For example, there is ItemsSource property in ItemsControl, declared in C++/WinRT :

IInspectable ItemsSource();

void ItemsSource(IInspectable value);

//The type of the object that you set the ItemsSource property to must implement one of these interfaces: IVector<IInspectable>, IBindableObservableVector etc.

Usually, it can be setup by C++/WinRT vector like:

control.ItemsSource(winrt::single_threaded_vector<winrt::hstring>(…))

Based on The Browser Company’s swift-winrt tools, its projections like:

public var itemsSource : Any! {

        get { try! _default.get_ItemsSource() }

        set { try! _default.put_ItemsSource(newValue) }

 }

But how to pass parameter of collection types into?

control.itemsSource = Array<String>[...].toVector()  // Crash, not working

Any help or hint is really appreciated, thank you !

Thanks to Mr.Saleem's "Interoperability: Swift's Super Power" and the old but still vary valuable book "Essential COM" from Mr.Don Box. Finally it works.

In summary:

  1. Didn't find any exsiting WinRT object implements both IInspectable and IVector, which is required by ItemsSource API. So that no swift projection class can be used directly;

  2. Swift can't build as COM object yet. Hope it can do in future;

  3. So need to create the COM object in C/C++, then wrapper with Swift, and set the property.

For example, in C++ :

::IInspectable * CreateIVector()
{
    auto vec = winrt::single_threaded_vector<winrt::Windows::Foundation::IInspectable>();
    vec.Append(winrt::box_value(L"Test"));
    vec.Append(winrt::box_value(L"Test2"));
    vec.Append(winrt::box_value(L"Test3"));
        
    auto inspectable_vec = vec.as<::IInspectable>();
    auto *raw_inspectable_ptr = inspectable_vec.get();
    raw_inspectable_ptr->AddRef();
    return raw_inspectable_ptr;
}

Then in Swift, based on swift-winrt of TBC :

let (com) = ComPtrs.initialize { abi in
    abi = CreateIVector()
}
let insp = WindowsFoundation.IInspectable(com!)
bread.itemsSource = insp

Hope above is useful for other people interested in Swift WinUI.

2 Likes