Monday, February 18, 2013

Monotouch NSDefaults and useful Keychain code.


Just some useful code.

public static class KeychainHandler
    {
        public static SecStatusCode HasCredentials(string generic)
        {
            var record = new SecRecord (SecKind.GenericPassword)
            {
                Generic = NSData.FromString(generic)
            };
            SecStatusCode result;
            var match = SecKeyChain.QueryAsRecord (record, out result);
            return result;
        }
        public static SecRecord Credentials(string generic)
        {
            var record = new SecRecord (SecKind.GenericPassword)
            {
                Generic = NSData.FromString(generic)
            };
            SecStatusCode result;
            var match = SecKeyChain.QueryAsRecord (record, out result);
            return match;
        }
        public static void DeleteKeychain(string generic)
        {
            SecKeyChain.Remove(KeychainHandler.Credentials(generic));
        }
}

To save NSDefaults for a User :

NSUserDefaults.StandardUserDefaults.SetString(yourstringvalue,yourstringkey);
NSUserDefaults.StandardUserDefaults.Init();

To Retrieve :

if(NSUserDefaults.StandardUserDefaults["whatever"] != null)
{
string value = NSUserDefaults.StandardUserDefaults.StringForKey("whatever");
}

Saturday, February 16, 2013

Monotouch and UTI handling.


Just making a demo app of Google Cloud Printing in Monotouch, and I wanted to be able to pass specific mime types to my app via Monotouch.  There isn't a recipe on the site for it, so I went about figuring out how to do it myself.

As you can see in your Monotouch Project Options, you need to navigate to "IPhone Applications", then go to the Advanced tab.  

Go to the "Document Types" list, and add on a Name.. then put in your type, which should resolve a text string listed by type here:  Apple UTI References

For PDF, you obviously put 'com.adobe.pdf'.



After entering that value, if you build your application, when you open a PDF in a documentview you should be able to see your application listed in the "Open In" action.


You still have some code to drop though, you need to be able to pass that file into your view controller. 
So, below is what you put in your appdelegate.cs to get access to the stream for the file that was passed in to your application.

public override bool HandleOpenURL (UIApplication application, NSUrl url)
{
    NSInputStream stream = NSInputStream.FromFile(url.Path);
    viewController.stream = stream;
    return true;
}

Monday, February 11, 2013

OData and Monotouch.



OData Service viewed through https://github.com/praeclarum/odata

Luckily, there are some code samples out there for getting OData, in a monotouch environment, and doing stuff with it.  Of course, there is always customization.  


To be honest, the greatest thing about this development pathway, is that all I have to do, for ForeignKeys is make sure I have the right web url.. for the OData service, and whammo.  I can populate any control on a base object the same way.  You can map these urls into a static helper tool, pass in your authorization header, or not, if you deploy via a mobile device framework and have a VPN.  

Basically, I'm having fun.  Hope you are too.  : )

Wednesday, February 6, 2013

DialogFragment Mono for Android.

Wanted to make a Dialog fragment, for uploading a picture from either the photo gallery in Android or from the Camera.  I wanted to really start doing a lot of dialogfragments.  I like that I can use them as fragments in activities or make them float above as dialogs.. Gives me twice the functionality as just making a normal fragment.   Of course, it does require at least 2.2 on the API side.

The Code:

public class CameraDialogFragment : DialogFragment
    {
        ImageButton camera;
        ImageButton gallery;
        
        public override Android.Views.View OnCreateView(Android.Views.LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {

            Dialog.Window.RequestFeature(WindowFeatures.NoTitle);

            var view = inflater.Inflate(Resource.Layout.CameraDialog, container, true);

            gallery = view.FindViewById<ImageButton>(Resource.Id.imageButton2);
            gallery.Click += delegate {

            };

            camera = view.FindViewById<ImageButton>(Resource.Id.imageButton1);
            camera.Click += delegate {

            };
            
            return view;
        }
        
        public override void OnResume()
        {
        
            Dialog.Window.SetLayout(LinearLayout.LayoutParams.WrapContent, LinearLayout.LayoutParams.WrapContent);
            
        
            Dialog.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));
            
        
            SetStyle(DialogFragmentStyle.NoFrame, Resource.Style.YouthImpactTheme);
            
            base.OnResume();
        }
        

        
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            

        }
        
    }

The XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageButton
        android:src="@drawable/Camera3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton1" />
    <ImageButton
        android:src="@drawable/Gallery"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton2" />
</LinearLayout>


The result: