Is it possible to share multiple links at once on Mac Catalyst to Messages? When I provide multiple urls via the UIActivityItemSource API Messages just picks 1 of the links.
The Mail activity handles multiple links without a problem but I'd like this to work with Messages too. I know for sure this is possible in native AppKit but can't seem to figure out how to get this to work on Catalyst.
I tried providing the links to UIActivityViewController with a UIActivityItemsConfiguration object instead of using the UIActivityItemSource API but that didn't work either.
Thanks in advance
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
According to the UIActivityViewController documentation for UIActivityViewController's completionWithItemsHandler:
Upon the completion of an activity, or the dismissal of the activity view controller, the view controller’s completion block is executed. You can use this block to execute any final code related to the service.
However when invoking the "Messages" or "Mail" actions in the UIActivityViewController this block is never called. I'm presenting the UIActivityViewController in a popover. Simple to reproduce. Just do this on Mac Catalyst in a table view delegate (sorry for the poor code formatting but it is hard to format code well on these forums).
-(UISwipeActionsConfiguration*)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
UIContextualAction *shareAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:@"Share"
handler:^(UIContextualAction *action,
UIView * _Nonnull sourceView,
void (^_Nonnull completionHandler)(BOOL))
{
[self showPopoverWithSourceItem:sourceView completionWithItemsHandler:^(UIActivityType _Nullable activityType,
BOOL completed,
NSArray * _Nullable returnedItems,
NSError * _Nullable activityError) {
//This block isn't called when Messages/Mail activities are selected. Probably other too but that's all I tested.
completionHandler(completed); //Need to call the UIContextualAction's completionHandler here to close up the swipe actions.
}];
}];
shareAction.image = [UIImage systemImageNamed:@"square.and.arrow.up.fill"];
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[shareAction]];
return config;
}
-(void)showPopoverWithSourceItem:(id<UIPopoverPresentationControllerSourceItem>)sourceItem
completionWithItemsHandler:(UIActivityViewControllerCompletionWithItemsHandler)handler
{
NSURL *shareLink = [NSURL URLWithString:@"https://www.apple.com"];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc]initWithActivityItems:@[shareLink]
applicationActivities:nil];
activityViewController.completionWithItemsHandler = handler;
activityViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *presentationController;
presentationController = (UIPopoverPresentationController*)activityViewController.presentationController;
presentationController.sourceItem = sourceItem;
presentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:activityViewController animated:YES completion:nil];
}
Run that and choose "Mail" or "Messages" in the activity view controller. The table view remains swiped after the activity is invoked and the popover is dismissed. Now if you click outside the popover without invoking an activity the popover dismisses and the completionWithItemsHandler is called.
Related but different UIActivityViewController/UIActivity bug I reported here yesterday: https://developer.apple.com/forums/thread/722003
I will file a bug on this and post the number here soon.
Can I please work a full day without running into a system bug in this framework....just one day..please.
I wouldn't be so disgruntled about all this if my obvious bug reports actually got fixed in a reasonable amount of time but I've been a developer long enough to know that I'm lucky if they get fixed for macOS 14, if ever.
Is there a way to programmatically determine the default size of an NSToolbarItem when creating them on Mac Catalyst like so:
UIImage *downArrowImage = [UIImage systemImageNamed:@"arrow.down"];
UIBarButtonItem *goDownUIBarButtonItem = [[UIBarButtonItem alloc]initWithImage:downArrowImage style:UIBarButtonItemStylePlain target:nil action:@selector(navigateDownard:)];
NSToolbarItem *nsToolbarItem = [NSToolbarItem itemWithItemIdentifier:itemIdentifier barButtonItem:goDownUIBarButtonItem];
Why am I asking? I need to create a toggle toolbar item (which requires me to change the toolbar item's image when the toggle is flipped.
I can do this by using NSUIViewToolbarItem and embedding a UIButton. But when you feed an SF Symbol image to UIButton and call sizeToFit on it it doesn't generate a view that matches the size of UIBarButtonItems for all the other NSToolbarItems next to it. I can hard code size constraints in like this to make it size properly:
NSLayoutConstraint *width = [theUIButtonToEmbedInToolbarItem.widthAnchor constraintEqualToConstant:32.0];
NSLayoutConstraint *height = [theUIButtonToEmbedInToolbarItem.heightAnchor constraintEqualToConstant:32.0];
//activate these constraints and embed the UIButton in the NSToolbarItem.
And that's works but I'm guessing the size so the layout could break in a OS update.
I tried just feeding an SF Symbol image to NSToolbarItem's image property directly but then the toolbar item doesn't draw at all (edit: this is only true when using an NSToolbarItem subclass, which I created to change the toolbar item's image itself when the toggle property is flipped)
//Inside my NSToolbarItem subclass.
-(void)setOn:(BOOL)isOn
{
if (_on != on)
{
_on = isOn;
self.image = (isOn) ? self.onImage : self.offImage;
}
}
So when using NSToolbaritem's image property directly setting the image property works fine, this means I have to track the toggle state externally which is possible but definitely not as nice).
Edit: Actually if forgot to modify my toolbar item subclass to subclass NSToolbarItem directly (was subclassing NSUIViewToolbarItem when I was first experimenting with using UIButton).
Using the image property on NSToolbarItem directly works for me. So I'm happy. I still think it'd be useful for clients that need to embed custom views inside a NSToolbarItem to get some kind of size recommendation.
When building context menus in UIKit I often have actions contained in a single method which can be invoked in different ways (from a UIButton, a UIBarButtonItem, etc.)
I'd like to simply make a menu item with a target-action pair but UICommand/KeyCommand only takes a selector. It seems kind of silly to have the system enumerate the responder chain in cases where I know who the target is supposed to be and there can and should only be one target (also could unintentionally create bugs when a responder implementing the same method gets the call instead of the target you want).
In AppKit you an easily do this with NSMenuItem. Could be a nice enhancement in UIKit. I know I can wrap the target in UIAction and call the selector in the action handler block but the code is kind of ugly and I'm not sure if there are edge cases where __weak __strong dance is required (in which case the code is even more long winded and ugly. I know swipe actions can occasionally create a retain cycle if you don't do __weak _ __strong dance).
Unless there is a UIMenuElement subclass that provides this and I'm just not aware of it?
When running into a hard to reproduce crash that only occurs in a production build it would be helpful to get more detailed information about the thrown exception. As far as I can tell, Crash reports don't include the NSException's name, reason, or userInfo. Is there any reason why this isn't included in Crash reports provided to developers?
Someone else asking something similar here: https://stackoverflow.com/questions/73327915/how-do-you-add-diagnostic-information-to-ios-crash-reports
Is there any UIKit API that bridges to NSBox in the Mac idiom?
The newer documentation about creating a Settings.bundle on Mac Catalyst simply links out to the Documentation Archive:
https://developer.apple.com/library/archive/documentation/PreferenceSettings/Conceptual/SettingsApplicationSchemaReference/Articles/PSGroupSpecifier.html#//apple_ref/doc/uid/TP40007009-SW1
The SupportedUserInterfaceIdioms key is documented:
Indicates that the element is displayed only on specific types of devices. The value of this key is an array of strings with the supported idioms. Include the string “Phone” to display the element on iPhone and iPod touch. Include the string to “Pad” to display it on iPad.
This key is available in iOS 4.2 and later.
Is "Mac" a supported entry to specify a preference for the Mac idiom? It seems to work but I don't see any documentation for this.
I'm trying to share a directory on my Mac with a virtual machine I created using the Virtualization framework. The virtual machine is running Fedora. I configure the share like this:
NSError *error = nil;
if ([VZVirtioFileSystemDeviceConfiguration validateTag:tag error:&error])
{
//Tag validates...
VZSharedDirectory *sharedDirectiory = [[VZSharedDirectory alloc]initWithURL:theURL readOnly:NO];
VZSingleDirectoryShare *singleDirectoryShare = [[VZSingleDirectoryShare alloc]initWithDirectory:sharedDirectiory];
VZVirtioFileSystemDeviceConfiguration *shareConfig = [[VZVirtioFileSystemDeviceConfiguration alloc]initWithTag:tag];
shareConfig.share = singleDirectoryShare;
virtualMachineConfiguration.directorySharingDevices = @[shareConfig];
}
The virtual machine starts up without any errors but the shared directory is nowhere to be found. Anyone know where am I'm going wrong?
Thanks in advance.
I have an area in my app where I load local HTML strings in WKWebView. Loading is fast on iOS. These local HTML strings are small.
On Mac Catalyst I added the ability to open this area of the UI in a new window scene (new window). And for some reason sometimes when I do this these simple HTML strings can take 10-15 seconds to load in the WKWebview in the new window.
These HTML strings are super small. I key value observed the loading property of the WKWebview and I hold the current date just before calling -loadHTMLString:baseURL:
Then when the web view completes loading I see how much time passed:
-(void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id>*)change
context:(void*)context
{
if (object == self.webview
&& [keyPath isEqualToString:@"loading"])
{
if (!self.webview.isLoading)
{
NSTimeInterval timeInterval = [NSDate.date timeIntervalSinceDate:self.loadStartDate];
NSLog(@"Web view took %f seconds to load",timeInterval);
}
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
Sometimes it is taking as long as 5 seconds to load a tiny HTML string. When opening these WKWebviews in the same window I don't get these long load times. But when I kick of WKWebView inside a new window scene I often do.
When playing a video in WKWebView I get this exception thrown after playing a video in "Full window mode" (that is when video takes over the size of the window, not to be confused with "full screen mode").
I'm running on Mac Catalyst.
#1 0x0000000188855800 in -[NSException raise] ()
#2 0x0000000189c2170c in -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] ()
#3 0x000000018968db9c in -[NSObject(NSKeyValueCoding) valueForKey:] ()
#4 0x000000018968da04 in -[NSObject(NSKeyValueCoding) valueForKeyPath:] ()
#5 0x00000001b9709a10 in -[AVPlaybackControlsController _observeBoolForKeyPath:usingKeyValueObservationController:observationHandler:] ()
#6 0x00000001b97066a8 in -[AVPlaybackControlsController _startObservingForPlaybackViewUpdates] ()
#7 0x00000001b9708ad4 in -[AVPlaybackControlsController _updatePlaybackControlsVisibleAndObservingUpdates] ()
#8 0x00000001b96db568 in __81-[AVPlayerViewController transitionController:willBeginPresentingViewController:]_block_invoke ()
#9 0x00000001b290f3ec in -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] ()
#10 0x00000001b28e01cc in -[_UIViewControllerTransitionContext _runAlongsideCompletions] ()
#11 0x00000001b28df984 in -[_UIViewControllerTransitionContext completeTransition:] ()
#12 0x00000001b972300c in __35-[AVTransition completeTransition:]_block_invoke ()
#13 0x00000001b96da368 in -[AVPlayerViewController transitionController:transitionWillComplete:continueBlock:] ()
#14 0x00000001b9736448 in -[AVTransitionController transitionWillComplete:success:continueBlock:] ()
#15 0x00000001b9722e44 in -[AVTransition completeTransition:] ()
#16 0x00000001b2b08a04 in -[UIViewPropertyAnimator _executeCompletionHandlerWithFinalPosition:] ()
#17 0x00000001b2b08ac4 in -[UIViewPropertyAnimator _runCompletions:finished:] ()
#18 0x00000001b2b07b10 in __61-[UIViewPropertyAnimator _setupAssociatedViewAnimationState:]_block_invoke ()
#19 0x00000001b375214c in UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK ()
#20 0x00000001b28e2258 in -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] ()
#21 0x00000001b28e1d8c in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
#22 0x00000001b297c330 in -[UIViewAnimationState animationDidStop:finished:] ()
#23 0x0000000213b66110 in -[UIViewAnimationStateAccessibility animationDidStop:finished:] ()
#24 0x000000018fe7e288 in CA::Layer::run_animation_callbacks(void*) ()
And the exception is: "[<WebAVPlayerController valueForUndefinedKey:]: this class is not key value coding-compliant for the key coordinatedPlaybackActive."**
Airplaying video doesn't seem to be working on Mac Catalyst (works on iOS). I'm on the same network.
Testing on Youtube. The "Airplay" button appears but clicking it does nothing. Anyone else experiencing this?
I set the elementFullscreenEnabled property on WKPreferences to YES. On iPad this enables web videos to be played in full screen.
However when I play the video and rotate the device, the layout becomes completely broken on orientation change. Anyone know of a workaround?
I can key value observe the web view's full screen state property but there is no obvious way to get ahold of the UI being used to play the video?
I'd like to ensure certain content doesn't overlap UISheetPresentationController's grabber.
In the view controller subclass that is being presented as a sheet via UISheetPresentationController I tried inspecting self.view.safeAreaInset.top hoping that this would account for the UISheetPresentationController's grabber but safeAreaInset.top is 0 unfortunately.
Right now I'm just using a hard coded value but is there API for this I overlooked?
Edit: Was able to resolve. This thread may be deleted.
I'm using a custom UIPresentationController. I'd like the replicate the behavior of UISheetPresentationController and allow user interaction the presenting view controller when the presented view controller does not cover the entire screen.
I tried this:
-(void)presentationTransitionDidEnd:(BOOL)completed
{
UIView *theView = self.presentingViewController.view;
theView.userInteractionEnabled = YES;
}
But has no effect. Is it possible to achieve this behavior? Thanks in advance