UISplitViewController created in xcode 6 with ios 7 Compatibility - uisplitviewcontroller

I want to create an app which uses UISplitViewController. I am using xcode 6 + ios 8.1 SDk. I had created sample app which works fine on iOS 8 (iPhone 5 , IPhone 6+, iPad) but fails on iOS 7. Does any one help me to implement this funtionality with supporting both iOS 7 & iOS 8.(Am using Language Objective C)

You actually can use UISplitViewController under iOS 7 (on iPhone or iPad), but there are a few tricks. First, I'm not sure if is possible programmatically but you should use a storyboard. Second, make sure you have Use Size Classes checkbox option enabled on the storyboard.
Lastly, there are also some issues where you may get called with a nav controller instead of the the split view controller. For example, in the default prepareForSeque method (provided by the default split controller project), I had to make the following #if 1 tweak:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = self.objects[indexPath.row];
#if 1
DetailViewController *controller = nil;
if ([segue.destinationViewController isKindOfClass:[UINavigationController class]]) {
controller = (DetailViewController*)[segue.destinationViewController topViewController];
}
else if ([controller isKindOfClass:[UISplitViewController class]]) {
controller = segue.destinationViewController;
}
#else
DetailViewController *controller = (DetailViewController*)[[segue destinationViewController] topViewController];
#endif
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
}
}

Related

How to share Preferences in a Xamarin.Forms project between an iOS and iOS extensions?

I'm trying to get a string (UserID) using Preferences.Get (Xamarin.Essentials) on a PushNotification.Extension project, but as the Preferences.Set happens in the Xamarin iOS project, I'm always getting an empty string in the extensions project.
Is there a way to share this preference between the iOS project and the iOS.extension?
public string UserID
{
get
{
return Preferences.Get(nameof(UserID), UserIDDefault);
}
set
{
Preferences.Set(nameof(UserID), value);
}
}
According to Apple docs , please follow the steps to enable data-sharinig .
Enable App Groups Capabilities , refer to App Group Capabilities in Xamarin.iOS.
Add the app to the App Group .
Use NSUserDefaults and init it with the name of the extension bundle identifier.
//Save
var defaults = new NSUserDefaults(#"com.example.domain.MyShareExtension");
defaults.SetString("value","Mykey");
defaults.Synchronize();
//Get
var defaults = new NSUserDefaults(#"com.example.domain.MyShareExtension");
var value = defaults.ValueForKey("Mykey");
"NSUserDefaults(string)" does not work for me.
In the Xamarin iOS documentation this constructor is marked as deprecated! see https://learn.microsoft.com/en-us/dotnet/api/foundation.nsuserdefaults?view=xamarin-ios-sdk-12
But when I use "NSUserDefaults(String, NSUserDefaultsType)" it runs perfect.

Android 12 In/out-call notification and prominent chip

According to Android 12 documentation there is special in/out-call notification that will show that called 'prominent chip'.
It's looking like that:
I tried to use the code from Android example:
// Create a new call with the user as caller.
Person incoming_caller = new Person.Builder()
.setName("Jane Doe")
.setImportant(true)
.build();
Notification.Builder builder = Notification.Builder(context, CHANNEL_ID)
.setContentIntent(contentIntent)
.setSmallIcon(smallIcon)
.setStyle(
Notification.CallStyle.forIncomingCall(caller, declineIntent, answerIntent))
.addPerson(incoming_caller);
In my application im using NotificationCompat and NotificationCompat.Builder
but this line Notification.CallStyle.forIncomingCall is refer to non Compat versions so I can't use the logic of forIncomingCall to my existing notification.
The NotificationCompat class from AndroidX hasn't been updated to include this new style yet - you can search NotificationCompat on https://cs.android.com to check the latest version of the file, and then you'll have to wait for a new release of the androidx.core:core library.
In the meantime, you'll have to use the platform Notification type if you want to use the new call style:
if (Build.VERSION.SDK_INT >= 31) {
// Use Notification with Notification.CallStyle
} else {
// use NotificationCompat
}

Xamarin Forms (VS2019) + iOS Intents UI: How to access Assets from Extension (IntentsUI)

I used the Xamarin version of SoupChef for Siri Intents. I was able to access the Container's Assets from the SoupChefIntentsUI.IntentViewController by requesting the bundle by identifier (using the BundleIdentifier of the main App) and then I just loaded the image by passing the bundle
CGSize DisplayOrderConfirmation(Order order, OrderSoupIntent intent, OrderSoupIntentResponse response){
/* unrelated code */
//this line work in the SoupChef example but
//On Xamarin.Forms this returns null
var containerBundle = NSBundle.FromIdentifier("com.something.SoupChef");
//always returns null because it seems it looks into the IntentsUI.Assets
var iconNull = UIImage.FromBundle("AppIcon");
//it returns the icon from the SoupChef.Assets
var iconNotNull = UIImage.FromBundle("AppIcon", containerBundle, configuration: null);
/* unrelated code */
}
I was also able to retrieve the AppIcon by creating the NSBundle doing something like this (in case you didn't want to assume that the bundle identifier names don't follow the Apple standard where the Container and the extensions have the same bundle identifier with the exception of the last segment)
CGSize DisplayOrderConfirmation(Order order, OrderSoupIntent intent, OrderSoupIntentResponse response){
/* unrelated code */
Class GetClassForType (Type type)
{
IntPtr myClassHandle = Class.GetHandle (typeToLookup);
if (myClassHandle != IntPtr.Zero)
return new Class (myClassHandle);
else
return null;
}
//this returns the bundle identifier of the SoupChef app
//(not the SoupChefIntentUI) on the SoupChef example
//on Xamarin.Forms (my project) it returns the IntentsUI identifier
var containerBundle = NSBundle.FromClass(GetClassForType(typeof(SoupChef.OrderIntent)));
//the icon is returned
var icon = UIImage.FromBundle("AppIcon", containerBundle, configuration: null);
/* unrelated code */
}
My problem is that I want to do the same thing on a different project that is using Xamarin.Forms, and the two previous ways that worked for me on the SoupChef project don't work here.
Is there a way to access the Assets set on the App.iOS.Assets or do I have to move them to the shared project where I have the models and other things that both the App.iOS and its Extensions are using?
I noticed that the Bindings (the project where the OrderIntent is) in the SoupChef example has the same namespace as the Container App ("SoupChef"), so I assigned the same namespace in my project with Xamarin.Forms and still nothing.

How to check tag of view in which touch occurred

I am developing a Xamarin.Forms application targeting the iOS platform. I want to only allow stylus input (i.e. disallow finger/direct input) in my entire app except for one single control (a SwitchCell).
For that, I implemented a custom UIApplication class and overrode the SendEvent(UIEvent uievent) method.
In SendEvent I am checking whether the event is a touch event using uievent.Type == UIEventType.Touches. Then I want to detect, if the touch occurred in the SwitchCell in which touch input should be allowed.
Because the SwitchCell is created in my Xamarin.Forms project as XAML, I implemented my own TaggableSwitchCell class inheriting from SwitchCell with a Tag property and registered a CustomRenderer that sets the Tag property of the UITableViewCell on iOS (which works as expected):
public class TaggableSwitchCellRenderer : SwitchCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
cell.Tag = (item as TaggableSwitchCell).Tag;
Log.Debug("Setting tag to " + cell.Tag);
return cell;
}
}
Then, in the SendEvent method, I check for the tag:
var isTouchAllowed = uievent.AllTouches.Any((touch) =>
{
var uitouch = touch as UITouch;
return uitouch.View != null && uitouch.View.ViewWithTag(Constants.Tag) != null;
});
Running this code on the device (iPad Pro 3rd Generation) works fine for every touch that is not in the SwitchCell. However, if the touch is in the SwitchCell (meaning isTouchAllowed should be true), the following message is printed (the app does not crash):
invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
I know, that the problem is with the uitouch.View.ViewWithTag(Constants.Tag) != null statement, but I don't know how to solve it. I already tried manually checking the view tag using uitouch.View.Tag == Constants.Tag but this leads to the same problem.

Detect default android browser by Wurfl

I want to detect default browser of android inside my MVC controller.
I have mobile detection right now:
public ActionResult Index()
{
if (WurflHelper.Instance.IsMobile(Request.UserAgent))
{
return View("MobileView");
}
else
{
return View();
}
}
How can i detect android default browser (not chrome). I need UserAgent parameters matches for this detection.
Thanks for advice.
--------------EDIT--------------------------------------------------------------
i found this solution for client (javascript) : How to detect the stock Android browser. I need same solution for asp.net MVC
I noticed that you are already using WURFL to detect the device. You could simply use the mobile_browser or advertised_mobile_browser capability to determine the browser of the device.
You can use this Request.Browser to get the browser info. Below is an example
var moo = Request.Browser;
var Name = moo.Browser;
var Version = moo.Version;
var Major_Version = moo.MajorVersion;
var Minor_Version = moo.MinorVersion;

Resources