Disassembling PowerShell commands to see how they work

If you ever wonder how PowerShell commands operate, what they do when you call them or how you can find out with the following commands what DLL the command is using and you can open the DLL with a disassembler like ILSpy.

$commandDetailsObj=Get-Command “your PS command here”

$commandDetailsObj.DLL

That is it, simple as that:).

 

XAMARIN DEVELOPMENT – NOTES, TIPS AND INFO – PART 2

Contents

Using Lists in iOS and Android. 1

iOS Lists. 1

Using the Table View controller. 4

Android Lists. 8

Populating the view(activity). 9

Creating a custom cell with custom style and layout. 9

Creating a custom adapter. 13

Navigation between pages in iOS and Android – Part 2. 15

Navigation between pages in Android. 15

Navigation between pages in iOS. 15

Navigate to the previous view controller. 16

Retrieve Images from iOS phone. 16

Sharing Code between Android, iOS or any other platform.. 17

iOS User Interface for different iOS devices using Constraints. 19

Tips and Tricks. 21

iOS. 21

Hiding the navigation controller. 21

Changing the look of the navigation bar. 22

Xamarin.Forms. 22

Xamarin.Forms is best for. 22

Xamarin.iOS & Xamarin.Android are best for. 22

Using Lists in iOS and Android

iOS Lists

· Add a new Table View Controller to your storyboard. From Visual Studio in your toolbox:

· Next drag the app start icon and associate it to the table view controller(This step is not necessary if you do not want the table view controller to be your first view which starts when your app starts.)

· Next create a new class to the table view by pressing on the dark gray area at the bottom of the view and in the Properties window under Identity there is an attribute named Class. Type in there a new class name which will then be automatically created and will appear in your Visual Studio project.

Using the Table View controller

· Use the Reuse Identifier to minimize the impact on loaded cell, in other words the amount of resources your application will need from the device, things like memory and CPU.

· To do this give a name to the first cell in the Table View Controller in the Identifier attribute in the Properties window.

Populate the table

· You can initialize data in the constructor function which is automatically created:

partial class BooksTableViewController : UITableViewController

{

List<Book> bookList;

public BooksTableViewController(IntPtr handle) : base(handle)

{

this.bookList = new List<Book>();

this.bookList.Add(new Book() { Author = "Author 1", Name = "Book 1", Editor = "Editor 1", Year = 2001 });

this.bookList.Add(new Book() { Author = "Author 1", Name = "Book 2", Editor = "Editor 1", Year = 2001 });

this.bookList.Add(new Book() { Author = "Author 1", Name = "Book 3", Editor = "Editor 1", Year = 2001 });

}

}

· This is just one way to do it:

1. Override the NumberOfSections() function and set how many sections you need.

a. https://developer.xamarin.com/api/member/MonoTouch.UIKit.UITableView.NumberOfSections()/

2. Override the RowsInSection() function set how many rows in the table will be, this could be the count number of a generic list.

a. https://developer.xamarin.com/api/member/MonoTouch.UIKit.UITableViewDataSource.RowsInSection/

3. Override the GetCell() function to define the cell data for each for being processed. This was defined in the RowsInSection() function. If you had three items in your data source then this function will be called three times. Using the indexPath.Row will get you the row indes which should “normally” correspond to the data source, assuming that the data source can be accessed by an index value.

a. https://developer.xamarin.com/api/member/MonoTouch.UIKit.UITableViewDataSource.GetCell/

public override nint NumberOfSections(UITableView tableView)

{

//return base.NumberOfSections(tableView);

return 1;

}

public override nint RowsInSection(UITableView tableView, nint section)

{

//return base.RowsInSection(tableView, section);

return bookList.Count;

}

// Returns a reusable cell, change it values and returns it to be added to the table view

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)

{

var cell = tableView.DequeueReusableCell("Book");

var dataInTheCell = this.bookList[indexPath.Row];

cell.TextLabel.Text = dataInTheCell.Name;

return cell;

//return base.GetCell(tableView, indexPath);

}

Modifying what is shown in a cell

· First create class for the table view cell. Go to your story board, in the table view controller select the cell in the upper most part, then go to the Properties window => Widget tab => Identity category and Class. In this attribute type the name of the class you want at it will be created.

· Next you modify how the cell looks or what it contains. You can simply add in new controls, give them a text that is shown by default and an identifier in the Identity category of the Properties window in the Widget tab.

· The next steps is to go to the previously defined table cell class and assign values to the controls in the table view cell. In this example there are four different labels which are set through an Book object which is passed to the table view cell.

partial class BookTableViewCell : UITableViewCell

{

private Book bookdata;

public Book BookData

{

get

{

return this.bookdata;

}

set

{

this.bookdata = value;

bookAuthorLabel.Text = bookdata.Author;

bookNameLabel.Text = this.bookdata.Name;

bookPublisherLabel.Text = this.bookdata.Editor;

bookYearLabel.Text = this.bookdata.Year.ToString();

}

}

public BookTableViewCell (IntPtr handle) : base (handle)

{

}

}

· The last step is to go into the code of the table view controller class an modify the GetCell() function code to use the custom table view cell class which you created previously. After this you can access any member function or property etc through code.

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)

{

var cell = tableView.DequeueReusableCell("Book") asBookTableViewCell;

var dataInTheCell = this.bookList[indexPath.Row];

cell.BookData = dataInTheCell;

return cell;

//return base.GetCell(tableView, indexPath);

}

Android Lists

· To create a list “view” simply modify a desired activity to inherit from ListActivity instead of Activity. Notice that the SetContentView() function is not called.

[Activity(Label
=
"BookStoreAndroid",
MainLauncher =
true,
Icon =
"@drawable/icon")]

public class MainActivity : ListActivity

{

int count = 1;

protected override void OnCreate(Bundle bundle)

{

base.OnCreate(bundle);

}

}

Populating the view(activity)

· You can populate the activity data in the OnCreate() function

public class MainActivity : ListActivity

{

List<Book> bookList;

protected override void OnCreate(Bundle bundle)

{

base.OnCreate(bundle);

// Set our view from the "main" layout resource

//SetContentView(Resource.Layout.Main);

// Get our button from the layout resource,

// and attach an event to it

this.bookList = new List<Book>();

this.bookList.Add(new Book() { Author = "Author 1", Name = "Book 1", Editor = "Editor 1", Year = 2001 });

this.bookList.Add(new Book() { Author = "Author 1", Name = "Book 2", Editor = "Editor 1", Year = 2001 });

this.bookList.Add(new Book() { Author = "Author 1", Name = "Book 3", Editor = "Editor 1", Year = 2001 });

}

}

· Next to define the data to be used in the list and the cell type you can do the following:

var listAdapter = new ArrayAdapter(this, global::Android.Resource.Layout.SimpleListItem1, this.bookList);

· The first parameter in the code is the context where the adapter is to be associated with. The second is the type of the cell in the list and the third parameter is the actual data.

· Next assign the ListAdapter member of the ListActivity class with the newly created listAdapter object.

this.ListAdapter = listAdapter;

· Notice that this approach will use the ToString() function of the class used in the List collection. So you have to override the ToString() function.

Creating a custom cell with custom style and layout

· First create a new layout: Go to your Solution Explorer, in your project go to the layout folder and press the second mouse button, then select Add => New Item, then select Android Layout from the new window.

· Next you can add layout elements to position your content and actual content elements like text elements. You could for example add LinearLayuout (Horizontal) and into them text elements (form widgets)

· Remember to set IDs to your UI elements to be able to access them and a text if you want to

Modifying the layout of an UI element

· This can be achieved from the Properties window under the Layout category. Just change the values in that category to modify how it is laid out .

Creating a custom adapter

· Simply create a new class in your android project

· In the newly created book adapter you have to do the following things:

o Inherit the class from the Android.Widget.BaseAdapter class

§ https://developer.xamarin.com/api/type/Android.Widget.BaseAdapter/

o Override the following function:

§ GetView()

§ GetItem()

§ GetItemId()

o The most important function is the GetView(), here you will retrieve the view that is holding your UI elements so that you can access them and modify their values.

public class BooksAdapter : BaseAdapter

{

public List<Book> books;

Activity activity;

public BooksAdapter(Activity activity)

{

this.activity = activity;

}

public override int Count

{

get

{

return this.books.Count;

}

}

public override View GetView(int position, View convertView, ViewGroup parent)

{

var view = convertView ?? activity.LayoutInflater.Inflate(BookStoreAndroid.Resource.Layout.BookCell, parent, false);

var nameLabel = view.FindViewById<TextView>(BookStoreAndroid.Resource.Id.nameTextView);

var authorLabel = view.FindViewById<TextView>(BookStoreAndroid.Resource.Id.authorTextView);

var publisherLabel = view.FindViewById<TextView>(BookStoreAndroid.Resource.Id.publisherTextView);

var yearLabel = view.FindViewById<TextView>(BookStoreAndroid.Resource.Id.yearTextView);

var data = this.books[position];

nameLabel.Text = data.Name;

authorLabel.Text = data.Author;

publisherLabel.Text = data.Editor;

yearLabel.Text = data.Year.ToString();

return view;

}

public override Java.Lang.Object GetItem(int position)

{

return null;

}

public override long GetItemId(int position)

{

return this.books[position].ID;

}

}

Navigation between pages in iOS and Android – Part 2

Navigation between pages in Android

Navigation between pages in iOS

· Generally, to navigate between pages you add new view controller in your storyboard and drag and drop from a UI Element to the desired view control to create a segue.

· After this you select the newly created segue and give it an identifier. You do this by selecting the desired segue and in the Properties window under the Widget tab in the Segue category type in the Identifier attribute

· To transition from using the right segue in the code you can do the following:

o https://developer.xamarin.com/api/property/MonoTouch.UIKit.UIStoryboardSegue.DestinationViewController/

o

public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)

{

if (segue.Identifier == "MySegue")

{

var navigationController = segue.DestinationViewController as MyViewController;

if (navigationController != null)

{

var rowPath = TableView.IndexPathForSelectedRow;

// Do something with the controller

}

}

}

Navigate to the previous view controller

· Use this simple code

NavigationController.PopViewController (true);

Retrieve Images from iOS phone

· Lets say that you have a button that you want to attach the TouchUpInside event. When this happens you want to allow the user to select an image from the phone.

void ImageButton_TouchUpInside(object sender, EventArgs e)

{

// Create a new image picker controller

imagePickerController = new UIImagePickerController();

imagePickerController.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;

imagePickerController.MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary);

// Attach yourself to the events which are needed

imagePickerController.Canceled += ImagePickerController_Canceled;

imagePickerController.FinishedPickingMedia += ImagePickerController_FinishedPickingMedia;

// Display the image picker as a modal view

NavigationController.PresentModalViewController(imagePickerController, true);

}

void ImagePickerController_FinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs e)

{

photoImageView.Image = e.Info[UIImagePickerController.OriginalImage] as UIImage;

// This returns the user to the previous view controller

imagePickerController.DismissModalViewController(true);

}

void ImagePickerController_Canceled(object sender, EventArgs e)

{

// This returns the user to the previous view controller

imagePickerController.DismissModalViewController(true);

}

Sharing Code between Android, iOS or any other platform

· This is rather simple, “normal” C# and Visual Studio stuff. the simplest approach is to create a class library, then create code in it which you want to use in your destination project. Once you are done with your shared class library simply Reference it in Visual Studio and make sure that you are using the right namespaces to access the classes or other code functionality defined in the shared projects.

· Notice: It has to be a portable class library. Otherwise you will not be able to use 3rd party libraries with your application.

· Next you choose your target platform which you want to use with your shared code.

· You could also use some predefined Xamarin project templates with this if you want.

iOS User Interface for different iOS devices using Constraints

· Scaling your application UI to work on different resolutions on different iOS devices

· A quick way to add constraints is to add it from the main.storyboard upper right corner after you have selected an UI control/element

· To specify manually constraints click once then another time on a UI element so that it looks something like this. Pay attention to the new options to specify constraints for the UI element, these are the T shaped icons near the edges of the element.

· To add a new constraint drag a T shaped icon to another element or the edge of the screen telling how the element should behave, how much space for example to leave between this element and another or the screen edge.

Tips and Tricks

iOS

Hiding the navigation controller

· In your view controller in the ViewDidAppear or ViewWillDisappear function call the SetNavigationBarHidden()

o Please notice the parameters to the function

public override void ViewDidAppear(bool animated)

{

base.ViewDidAppear(animated);

this.NavigationController.SetNavigationBarHidden(true, false);

}

Changing the look of the navigation bar

· You can do this in the AppDelegace.cs file/class, in the overridden function FinnishedLaunching

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)

{

// Override point for customization after application launch.

// If not required for your application you can safely delete this method

var navigateionVarAppearance = UINavigationBar.Appearance;

navigateionVarAppearance.TintColor = new UIColor(255.0f, 255.0f, 255.0f, 1.0f);

navigateionVarAppearance.BarTintColor = new UIColor(255.0f, 255.0f, 255.0f, 1.0f);

navigateionVarAppearance.SetTitleTextAttributes(new UITextAttributes()

{

TextColor = new UIColor(255.0f, 255.0f, 255.0f, 1.0f),

TextShadowColor = UIColor.Clear

});

return true;

}

Xamarin.Forms

https://www.xamarin.com/forms

From the website:

Xamarin.Forms is best for

· Apps that require little platform-specific functionality

· Apps where code sharing is more important than custom UI

· Developers comfortable with XAML

Xamarin.iOS & Xamarin.Android are best for

· Apps with interactions that require native behavior

· Apps that use many platform-specific APIs

· Apps where custom UI is more important than code sharing

SharePoint Search and changing the Created and LastModified fields

If you want to change the LastModified and Created fields of a list item or a document you can use this code to do that:


SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite("site + web url"))
{
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPListItem listItem = web.GetListItem(this.tbItemURL.Text);

if (this.cCreatedDate.SelectedDate != new DateTime())
listItem[SPBuiltInFieldId.Created] = this.cCreatedDate.SelectedDate;
else
listItem[SPBuiltInFieldId.Created] = listItem[SPBuiltInFieldId.Created];

if (this.cModifiedDate.SelectedDate != new DateTime())
listItem[SPBuiltInFieldId.Modified] = this.cModifiedDate.SelectedDate;
else
listItem[SPBuiltInFieldId.Modified] = listItem[SPBuiltInFieldId.Modified];

listItem.UpdateOverwriteVersion();
if (listItem.ParentList.EnableMinorVersions)
{
listItem.File.Publish("SPFileUpload");
}
if (listItem.ModerationInformation != null)
{
listItem.File.Approve("SPFileUpload");
}




web.AllowUnsafeUpdates = false;
}
}
});

The reason why the above is done is because if you simply change the date values and use the UpdateOverwireVersion() it will not be enough. The search will not be able to index right values EVEN if you check the UI or use PowerShell or SharePoint Manager etc. All of those show that the value is OK but actually is not. The manually inserted dates will not show up in search unless the item or document is published and approved. So no matter that SP says remember this:).

another thing is that this code above does not allow to set a LastModified IF you have publishing/versioning enabled. After calling the UpdateOverwriteVersion function the item or document will be checked out and remains in that state until something is done. Once you do that you are back to where you started the modified date is changed automatically by SP.

Do not have a solution yet. Maybe you have?

Xamarin Development – Notes, tips and info – Part 1: How to develop your first iOS and Android Apps

Hi,

This is series of posts and my notes and info which are based on a Udemy course. I’ve taken what I consider “good to know” and wrote them down. This may come handy to someone else.

Contents

What is Xamarin. 2

Xamarin Platform.. 2

Xamarin Test Cloud. 2

Xamarin Insight. 2

Debugging Android applications. 3

Xamarin Platform.. 4

C# as the language for your mobile app development. 4

Share your C# code on any platform.. 4

Device provisioning/installation of your app. 4

First iOS Application. 4

Basic iOS controls: 5

Properties window.. 5

Naming UI Controls. 5

Events. 6

UI Elements. 6

Different Keyboard types. 6

Changing background colors. 7

Tips and Tricks. 7

First Android Application. 7

Basic Androi controls. 7

Naming UI Controls. 7

Accessing UI elements in the code. 8

UI Elements. 9

Different Keyboard types. 9

Navigation between pages in iOS and Android. 9

Navigation between pages in Android. 9

Adding a new layout and activity. 10

Using Intents to navigate. 10

Passing values between activities (pages/layouts). 10

Navigation between pages in iOS. 11

Adding a new navigation controller. 11

Passing values between views/segues (pages/layouts). 15

What is Xamarin

Xamarin Platform

Building applications on mobile devices

Xamarin apps share code across all platforms

Target i0S, Android, Windows and Mac with a single, shared C# codebase. Use the same language, APIs and data structures on every platform.

C# is the best language for mobile app development

Anything you can do on Objective-C, Swift or Java, you can do in C#

Native UI, native API access, native performance

Xamarin apps are built with standard, native user interface controls. Apps not only look the way the end user expects, they behave that way too. This can’t be achieved with other solutions. They look and behave as they would on that native environment (Android. iOS, Windows Phone)

Xamarin Test Cloud

Test your applications on different devices

Test your app on over 1,000 devices

Run your app on a huge collection of real devices from around the world. Select devices based on form factor, manufacturer, operating system, or even popularity in your target market.

Automate using Ruby or C#

With a framework called Calabash you can automate and test any iOS or Android app, native or hybrid, from the UI level down for perfect integration and continuous improvements.

Analyze app performance

See full-frame screenshots and video playback for every step of every test, then receive performance data and compare reports against previous runs to find regressions and bottlenecks.

Xamarin Insight

Monitoring your applications

Precise, detailed error reporting

Xamarin Insights helps developers prioritize issues by showing exactly which users each crash is impacting, and what sequence of actions preceded the crash.

Understand how users are interacting with your app

Developers can see who’s online, which devices they’re using, what issues they’ve experienced, where they’re from, and which activities they’ve used in sessions.

Integrate your data

Connect your app to a variety of external services and be notified when a new issue is opened, an issue is occurring repeated times in a small amount of time, or an issue’s status changes.

· Github

· Visual Studio Online

· …

Debugging Android applications

· You can use normal Android Virtual Devices with the SDK

· for a FASTER experience use the Xamarin Android Player: https://www.xamarin.com/android-player

o You also avoid using Hyper-V on Windows

Image: 1 Xamarin Android Player

o To Use the Android Player just go to your Visual Studio toolbar and select a device in this case the device installed in Image: 1 Xamarin Android Player

Image: 2 Example how to use the Android Player

Xamarin Platform

C# as the language for your mobile app development

· Anything you can do in Objective-C, Swift, Java, you can do in C#

· Things which are better than competition(at the present)

o Stronger Types

§ Generics and Compound types are used safely

· No need for casting of comments

· Good tools that understand what you are doing

o Language-level async, made easy in C#

o First-class functions, lambdas are easy to use

Share your C# code on any platform

· Possible to share on average about 75 % of your code across platforms

o Most of it at app logic, common functionality

o Could also be at UI level

§ Xamarin.Forms could be used in theory to achieve 100 % shareable code

Device provisioning/installation of your app

· iOS – Two options:

o Enroll to the Apple Developer Program:

§ https://developer.xamarin.com/guides/ios/getting_started/installation/device_provisioning/

o Or with Xcode 7 use free provisioning:

§ https://developer.xamarin.com/guides/ios/getting_started/installation/device_provisioning/free-provisioning/

First iOS Application

· Start with a single view app

· Main.Storyboard we define the UI

· ViewController.cs the main logic goes here

· iOS UI design on implementation requires more work to make it work and look good across different iOS devices

· By default the main.storyboard is linked to the ViewController.cs.

Basic iOS controls:

· Label

· TextField (for inputing data)

· Button

Properties window

· Widget tab

o You can alter button properties such as:

§ Color and how it looks

§ Title

§ Font

§ ID

§ etc

· Layout tab

o How the control is laid out on the UI

· Events tab

o How the user interacts with the control through touch

Naming UI Controls

· This can be achieved through the properties window.

o Select the desired UI control from the main.storyboard

o Go to the Name text field under the Identity category

o Notice: This is a physical name, meaning that you use this in the code to access the control

Events

· When users click/touch on buttons an event is launched.

· You can attach to a click event through the UI or through code by normal C# event handling in the ViewDidLoad() function in the ViewController.cs file

public override void ViewDidLoad()

{

base.ViewDidLoad();

// Perform any additional setup after loading the view, typically from a nib.

this.convertButton.TouchUpInside += ConvertButton_TouchUpInside;

}

UI Elements

Different Keyboard types

· You can select different types of keyboard by selecting a text field and under Keyboard Type select the desired keyboard output

Changing background colors

To change the background color of a control simply change the BackgroundColor property. Example>

this.colorView.BackgroundColor = UIColor.FromRGB(redValue, greenValue, blueValue);

Tips and Tricks

Using this.View.EndEditing(true); will end/hide the editing keyboard.

First Android Application

· For Visual Studio development you need Hyper-V to emulate an android device

Basic Androi controls

· Under Text fields category you will find normal input controls

· Under form widgets you will find basic button and plain text controls

Naming UI Controls

· This is found in the properties window under the Main category and in there ID

Accessing UI elements in the code

· In an Android application you have to find the controls manually and assign them to a variable of the same type.

· You use the FindViewById<>() function call. You pass the class type to the template(generic) parameter, then pass the control ID by accessing your project namespace then Resources class, then Id class and finally the control ID which you define in your layout.

Example:

using Android.Runtime;

using Android.Views;

using Android.Widget;

using Android.OS;

namespace BMICalculationAndroid

{

[Activity(Label
=
“BMICalculationAndroid”,
MainLauncher =
true,
Icon =
“@drawable/icon”)]

public class MainActivity : Activity

{

Button calculateBMI;

TextView resultTextView;

EditText heightEditText, weightEditText;

protected override void OnCreate(Bundle bundle)

{

base.OnCreate(bundle);

// Set our view from the “main” layout resource

SetContentView(Resource.Layout.Main);

this.calculateBMI = FindViewById<Button>(BMICalculationAndroid.Resource.Id.calculateBMI);

this.resultTextView = FindViewById<TextView>(BMICalculationAndroid.Resource.Id.resultTextView);

this.heightEditText = FindViewById<EditText>(BMICalculationAndroid.Resource.Id.heightEditText);

this.weightEditText = FindViewById<EditText>(BMICalculationAndroid.Resource.Id.weightEditText);

}

}

}

UI Elements

Different Keyboard types

· To change to keyboard type when typing on a mobile device you do it similarly as on the iOS side

o In the properties window go to Main – Input Format => inputType and change the keyboard type

Navigation between pages in iOS and Android

Navigation between pages in Android

Adding a new layout and activity

· This allows you to create another UI view/page that is to be displayed in your application

To do this in Visual Studio go to the Resources/Layout folder and add a new item. From the Add New Item window select the Android Layout option.

Then create new activity code class which will operate on the newly created layout.

You can create this for example in your project root by adding again a new item there.

Then to create the link and set the content between the layout and the activity call the SetContentView() function.

protected override void OnCreate(Bundle savedInstanceState)

{

base.OnCreate(savedInstanceState);

// Create your application here

SetContentView(Resource.Layout.BMIDetails);

}

Using Intents to navigate

· You navigate to another layout(page) by using the Intent class

· You can use the constructor that takes the present content and the desired activity class associated with the layout

· Then you start the activity and move to the other layout(page) by calling the StartActivity() function

var intent = new Intent(this, typeof(BMIDetailsActivity));

StartActivity(intent);

Passing values between activities (pages/layouts)

· In the activity from where you want a value to be passed to another activity you use the Intent class member function named PutExtra() to store the value. It is a key value pair which can be retrieved in another activity later:

var intent = new Intent(this, typeof(BMIDetailsActivity));

intent.PutExtra(“bmi_value”,this.bmi);

StartActivity(intent);

· And to restore the value you access it through the activity Intent class member by accessing from it the Extras member. From there use the GetFloat() function.

var bmi = Intent.Extras.GetFloat(“bmi_value”);

Navigation between pages in iOS

Adding a new navigation controller

· Drag and drop a new navigation controller

· If you already have a root view controller, then remove the one which was created by the previous operation (Press the mouse second button on the view controller and press delete)

· Next move is to indicate to the application what is the starting view (Apple story board naming is: sourceless seque). You are using a sourceless seque indicator: https://developer.xamarin.com/guides/ios/user_interface/introduction_to_storyboards/

o Drag and drop it on the navigation controller

Image: 3 it should look something like this

· Next create a relationship between the navigation controller and the main view by pressing CTRL + left mouse button on the navigation controller and dragging the mouse over the main view. Then you select the Root option from the new popup. This will mark the main view as the root view.

· Next drag a new view on the storyboard and give it a name. Once you do this the developer tool will warn you that there is no code behind class associated with the view(In Xamarin Studio the UI will offers you to create one). In Visual Studio the easiest way to do it is to press the dark grey area on the view without a controller and writing a new class name in the Class property in the properties window. This will create a new view controller associated to the view selected.

· To navigate from your Main(root) view just select a control that can be pressed like a button, press CTRL + left mouse button on it, then drag to the desired view and let go of the mouse button. In the new popup select Show. This is it. A connection and transition has been made between the views.

Passing values between views/segues (pages/layouts)

· To pass a value between views/segues you can override the function PrepareForSegue() which is launched when the segue is about to be used, that is when the user presses a button or some other UI element which invokes the action of moving from one view/page/layout to another one. What was done earlier.

· In the function you then access the parameter segue and ask for the DestinationViewController class member which you have to cast to the target view controller class. After that it is simply of matter of accessing the defined properties in the view controller class. Same as accessing any public member of a class.

public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)

{

base.PrepareForSegue(segue, sender);

var detailViewController = segue.DestinationViewController asBMIDetailsViewController2;

if(detailViewController != null)

{

detailViewController.bmi = this.bmi;

}

}

PowerShell script how to backup lists and restore them in another location through list templates

Ok, this is one way of doing this. Perhaps this is useful in a situation where you need to backup lists with their data from an older SharePoint version and restore it in another SharePoint version. Preferably doing this quickly without worrying about site templates or something more than the list and its data.

The script below gets lists in a target web location, saves them as list templates and download them in the hard drive.

Approach 1: Export the list through Export-SPWeb and restore with Import-SPWeb

param (
 [string]$SPSiteFilter = "http://portal.spdev.com/",
 [string]$SPWebFilter = "http://portal.spdev.com/",
 [string]$SPWebFilterRelative = "",
 [string]$destination = "C:\\temp"
 )
 
 $site = Get-SPWeb $SPSiteFilter
 
 
 # Get the webs lists and save them as list templates
 $lists = $site.lists
Foreach ($list in $lists) {
Write-Host $list.BaseType
 if($list.Hidden -eq $false -and $list.BaseType -eq "GenericList")
 {
 Write-Host $list.Title + " " + $list.RootFolder.ServerRelativeUrl
 
 $filePath = $destination + "\" + $list.Title + ".cmp"
 $itemURL = $SPWebFilterRelative + $list.RootFolder.ServerRelativeUrl
 Write-Host $filePath
 Write-Host $itemURL
 Write-Host $SPWebFilter
 export-spweb -identity $SPWebFilter -path $filePath -itemurl $itemURL –includeusersecurity
 #$list.SaveAsTemplate($list.Title+ " " + $ListTempalteIDPostFix,$list.Title,"Site list Backup",1)
 }
 }

 $site.Dispose()
param (
 [string]$SPSiteFilter = "http://portal.spdev.com/subsite/",
 [string]$source = "C:\\temp"
 )
 
 $site = Get-SPWeb $SPSiteFilter
 
 Get-ChildItem $source -Filter *.cmp | 
Foreach-Object {
 Write-Host $_.FullName
 #Upload the list temaplte to the list templates gallery
 Import-SPWeb -identity $SPSiteFilter -path $_.FullName –force
 
}

$site.Dispose()

Approach 2: As list templates


param (
[string]$SPSiteFilter = &quot;http://site/&quot;,
[string]$SPWebFilter = &quot;http://site/myweb/&quot;,
[string]$ListTempalteIDPostFix = &quot;SU&quot;,
[string]$destination = &quot;C:\\temp&quot;
)

$site = Get-SPSite $SPSiteFilter
$web = Get-SPWeb $SPWebFilter
$templatesLibrary = $site.RootWeb.GetListFromUrl(&quot;/_catalogs/lt/Forms/AllItems.aspx&quot;)

if(!$templatesLibrary)
{
Write-Host &quot;List template gallery not found. Program execution halted.&quot;
return
}

# Get the webs lists and save them as list templates
$lists = $web.lists
Foreach ($list in $lists) {
Write-Host $list.BaseType
if($list.Hidden -eq $false -and $list.BaseType -eq &quot;GenericList&quot;)
{
Write-Host $list.Title
$list.SaveAsTemplate($list.Title+ &quot; &quot; + $ListTempalteIDPostFix,$list.Title,&quot;Site list Backup&quot;,1)
}
}

# Read the list templates from the gallery and save them to the hard drive
$folder = $templatesLibrary.RootFolder
foreach ($file in $folder.Files) {
#Ensure destination directory
$destinationfolder = $destination

#Download file
$binary = $file.OpenBinary()
$stream = New-Object System.IO.FileStream($destinationfolder + &quot;/&quot; + $file.Name), Create
$writer = New-Object System.IO.BinaryWriter($stream)
$writer.write($binary)
$writer.Close()

}
For ($i=$folder.Files.Count; $i -gt 0 -or $i -eq 0; $i--)
{
$folder.Files[$i].Delete()
}

$web.Dispose()
$site.Dispose()

This script uploads the list templates into the targeted SharePoint site.

param (
[string]$SPSite = &quot;http://portal3.dev.com/sites/sc&quot;,
[string]$SiteTemplatesLocation = &quot;C:\\temp&quot;,
[string]$SiteTemplatesGalleryName = &quot;List Template Gallery&quot;
)
# $site = Get-SPSite $SPSiteFilter
# $web = Get-SPWeb $SPSiteFilter
# $templatesLibrary = $site.RootWeb.GetListFromUrl(&quot;/_catalogs/lt/Forms/AllItems.aspx&quot;)
# $Files = $templatesLibrary.RootFolder.Files

Function UploadListTemplate($WebURL, $TemplateFilePath)
{
#Get the Web
$web = Get-SPWeb $WebURL
#Get the List template Gallery Folder
$TemplateFolder = $web.GetFolder($SiteTemplatesGalleryName)
#Get the Files collection
$TemplateFileCollection = $TemplateFolder.Files
#Get the Template file from Local File system
$TemplateFile = Get-ChildItem $TemplateFilePath

#Open the File in Read mode and Add to Templates collection
$TemplateFileCollection.Add(&quot;_catalogs/lt/$($TemplateFile.Name)&quot;, $TemplateFile.OpenRead(), $true)
Write-Host &quot;Done!Template has been uploaded!!&quot;
$web.Dispose()

}

Get-ChildItem $SiteTemplatesLocation -Filter *.stp |
Foreach-Object {
Write-Host $_.FullName
#Upload the list temaplte to the list templates gallery
UploadListTemplate $SPSite $_.FullName

}

This script will create the lists based on the list templates NOTICE that this does not differentiate between existing list templates not uploaded with the script above.

 param (
 [string]$SPSiteFilter = &quot;http://portal3.dev.com/sites/sc&quot;,
 [string]$ListTempalteIDPostFix = &quot;SU&quot;,
 [string]$destination = &quot;C:\\temp&quot;
 )

 $site = Get-SPSite $SPSiteFilter
 $web = Get-SPWeb $SPSiteFilter

 # Create lists based on the list templates
$site.GetCustomListTemplates($web) |
Foreach-Object {
if($web.Lists.TryGetList($_.Name.Replace($ListTempalteIDPostFix,&quot;&quot;)) -eq $null)
{
 $web.Lists.Add($_.Name.Replace($ListTempalteIDPostFix,&quot;&quot;), $_.Description, $_)
 }
}

 $web.Dispose()
 $site.Dispose()
 

If your list has content that is too large to save as a template try to run this script and remember to change to the default value which I think should be: 52428800


$docSize = 500000000
$webservice = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$webservice.MaxTemplateDocumentSize = $docSize
$webservice.Update()

Prerequisites for custom list templates

SharePoint List must meet the following criteria to move a list by using a list template (source):

  • The list must contain less than 10 megabytes (MB) of list data.
  • You must be a member of a site group with the Manage Lists right on the source site and on the destination site. By default, the Manage Lists right is included in the Web Designer and Administrator site groups.
  • The source site and the destination site must be based on the same site template.

How to use Microsoft Graph to get office groups listed in a native (Console) application

To get groups from using Microsoft Graph you have to do the following things:

  • Register an application using Azure AD and give required privileges to the application
  • Request a token for your application using the client ID and client secret key
  • Make the API call to using REST by specifying that your realm where to get the groups from

Register your application through Azure AD

Go to https://portal.azure.com/ or https://manage.windowsazure.com

Next from the Azure navigation go to your active directory. Next you should see different options in the top area of the your AAD, such as:

Users, Groups, Applications, Domain and so on.

Select the Applications section.

aad1

Next you should get a listing of applications configured in your AAD.

Next from the AAD UI select ADD to add a new application.

aad2

Select what type of an application it is. You can use both option. I used the configurations of an MVC application which allowed me to work just fine. What matters is the client ID, client secret key and the privileges. The redirect URL is not necessary for a Native Application, you can type in anything as long as it is a URL.

aad4aad5

 

After your application is created go to the configure section.

aad6

Here find the client ID and copy store it somewhere to be used later.

Then go to the keys section and add a new key(client secret)

aad7

Then scroll down and go the applications section and add the Microsoft Graph application and select the needed privileges. In this case, you would like at least to be able to read groups.

aad8aad9

That is it, next is some code.

Request a token for your application

This is the piece of code that will get the token from your application. The constants and parameters will be explained soon.

public static string GetTokenForApplication(String realm, String clientId, String clientSecret)
 {
 AuthenticationContext authenticationContext = new AuthenticationContext(Constants.UnifiedApiConnect.AzureADAuthority + realm, false);
 // Config for OAuth client credentials 
 ClientCredential clientCred = new ClientCredential(clientId, clientSecret);

 AuthenticationResult authenticationResult = authenticationContext.AcquireToken(Constants.UnifiedApiConnect.O365UnifiedAPIResource,
 clientCred);
 string token = authenticationResult.AccessToken;
 return token;
 }

Make the API Call to get the groups

This is the code that will get the token and request data from the Graph API


TokenHelper.Token = Program.GetTokenForApplication(realm, clientId, clientSecret);
 List&amp;lt;Group&amp;gt; groups = new List&amp;lt;Group&amp;gt;();
 string APIURL = Constants.UnifiedApiConnect.O365UnifiedAPIResource + "v1.0/" + realm + "/groups?$filter=groupTypes/any(c:c+eq+'Unified')";
 try
 {
 groups = GroupsHttpHelper.GetGroups(APIURL);
 foreach (var group in groups)
 {
 groupsSite.Add(new SiteDirectoryEntity() { Title = group.displayName, URL = String.Format(Program.O365OutlookMailGroupURL, realm, realmLCID, group.mail) });
 }
 }
 catch (Exception ex)
 {
 Logger.Error("Error in processing O365 groups through MS Graph: " + ex.Message + "\n" + ex.StackTrace);
 }

This is the code that will do the request to the Graph API, notice that the data is deserialized into objects.

 


public class GroupsHttpHelper
 {
 public static List&amp;lt;Group&amp;gt; GetGroups(string apiUrl)
 {
 if (String.IsNullOrEmpty(apiUrl)) { throw new ArgumentNullException("apiUrl"); }

 List&amp;lt;Group&amp;gt; groups = new List&amp;lt;Group&amp;gt;();

 string responseContent = GroupsHttpHelper.GetHttpResource(apiUrl);
 var responseObject = JsonConvert.DeserializeObject&amp;lt;GraphResponse&amp;lt;Group&amp;gt;&amp;gt;(responseContent);
 foreach (var item in responseObject.value)
 {
 groups.Add(item);
 }

 return groups;

 }

 public static string GetHttpResource(string url)
 {
 string responseContent = String.Empty;

 string token = TokenHelper.Token;

 var request = (HttpWebRequest)HttpWebRequest.Create(url);

 request.Method = "GET";
 request.Accept = "application/json";
 request.Headers.Add("Authorization", "Bearer " + token);

 var response = request.GetResponse();
 using (var reader = new StreamReader(response.GetResponseStream()))
 {
 responseContent = reader.ReadToEnd();
 }

 return responseContent;
 }
 }

public class Group
 {
 public string accessType { get; set; }

 public bool? allowExternalSenders { get; set; }

 public bool? autoSubscribeNewMembers { get; set; }
 public string description { get; set; }
 public string displayName { get; set; }
 public string[] groupTypes { get; set; }
 public string id { get; set; } // identifier

 public bool isSubscribedByMail { get; set; }
 public string mail { get; set; }

 public bool? mailEnabled { get; set; }
 public string mailNickname { get; set; }
 public string onPremisesLastSyncDateTime { get; set; } //timestamp
 public string onPremisesSecurityIdentifier { get; set; }

 public bool? onPremisesSyncEnabled { get; set; }
 public string[] proxyAddresses { get; set; }

 public bool? securityEnabled { get; set; }
 public int unseenCount { get; set; }
 public string visibility { get; set; }
 }

Namespaces needed in the code:

using Microsoft.Online.SharePoint.TenantAdministration;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;

NuGet Packages needed:

Active Directory Authentication Library – Id: Microsoft.IdentityModel.Clients.ActiveDirectory
Json.NET – Id: Newtonsoft.Json

WebConfig Values and parameters in the code

 

<add key=”MSGraphGourps_Realm” value=”yourrealm.com” />

<add key=”ClientId” value=”your client ID in the Azure AD application” />
<add key=”ClientSecret” value=”your client secret key in the Azure AD application” />

The URL format for the authentication context request is something like this: https://login.microsoftonline.com/yourrealm.com

To acquire the token: https://graph.microsoft.com/

To get the groups the URL is: https://graph.microsoft.com/1.0/yourrealm.com/groups

If you are not sure where to get your realm from there are two ways:

  1. Get it from the URL in your browser bar when you are viewing an O365 outlook mail box or group: https://outlook.office.com/owa/?realm=yourrealm.com
  2. The other option is to use the Azure Management UI and again in the url your should find it: https://manage.windowsazure.com/yourrealm.com

 

Getting other information from Groups

One Drive:

https://graph.microsoft.com/v1.0/your realm name/groups/{your group guid}/drive/root

Owners:

https://graph.microsoft.com/v1.0/your realm name/groups/{your group guid}/owners

Group Logo:

 

PnP Partner-Pack Site Provisioning: Weirdness, quirks and guide

If you have been playing around with the Site Provisioning in the PnP Partner Pack you might have run into problems when installing it. While the instructions are rather good there are still some problems which I ran into and are not mentioned in the instruction(or I might have just passed by them).

Notice that the things mentioned here assumes that you have read or understand how to install the site provisioning web app by this instruction:

https://github.com/OfficeDev/PnP-Partner-Pack/blob/master/Documentation/Manual-Setup-Guide.md

Anyway here is what is good to know:

Sign-ON URL format:

When you are defining your Sign-On URL in the Configure section for your application, there is a very weird and annoying error that the site provisioning web application might throw. This is due that you are missing one single character from the end of your URL which is: /

Example:

URL which does not work: https://pnpprovisioning82.azurewebsites.net

URL which does work: https://pnpprovisioning82.azurewebsites.net/

Do you see the difference :)? Small but enough to make you wonder. The error message is not necessarily very informative and unfortunately I do not have that error message anymore, can paste it here. Just check this thing in case of errors.

The webjobs…:

Installation

The web jobs are good and working BUT the installation is a bit misleading. I had to figure out for myself and gather the info from different locations. My problem was that the script which was supposed to install the jobs automatically did not work. Some error which did no make sense and I did not want to spend time figuring out. If it works for you then that is great. If not you might have to do this manually.

You have different way on how to do this manually:

  1. Through Azure portal management
  2. Through visual studio

 

Azure portal management

  1. Build a release version of the webjob
  2. Just zip the entire release folder and rename your zip package
  3. Go to your web application web jobs section
  4. Click add a new job and upload your ZIP file and define how you want your job to run

 

Visual Studio

On the web job project which you want to upload to Azure press the second button and chose  “Publish as Azure Webjob” and follow the instructions.

You might want to take advantage of the Azure management UI by downloading a publishing profile from your web application dashboard. You can use this publishing profile in Visual Studio.

The webjobs what they do

OfficeDevPnP.PartnerPack.ContinousJob

This is the one which will be reading the PnPProvisioningJobs list and create jobs to be processed by the other webjobs. You have to have this on to get anything done, mostly related to site provisioning. I might be wrong on some of the details here but having this on is essential.

OfficeDevPnP.PartnerPack.ScheduledJob

My understanding is that his job is what is provisioning the sites and creating templates of sites.

 

Guide – What is where or how things work

The web application overall UI functionality

As is mentioned in this documentation there are several views(pages) which are used with the site provisioning. Notice that not all of them are available through the web application UI and this in my opinion is confusing.

Some of the functionalities are only available in a actual site:

  1. Creating a new sub site
    1. This is only available when you go to a site, from “site settings” select “site contents”. The PnP Partner Pack overrides the default “New subsite” link. I kind of understand this but was not the first place where I expected it to be.
  2. Saving a site template
    1. This can be found under your site “site settings” in the category “site actions”. There is a JS file which is attached to your PnP sites which add a new link here named as “Save site as Provisioning Template”.

The JS file is located in the infrastructure site in the Library: PnPProvisioningTemplates under the folder: Overrides. Through the XML file in this location the JS file is loaded and the two above mentioned things are performed.

Infrastructural Site Collection

What is mean by this is that this is a “dummy” site collection created by you and then you apply the steps(script) https://github.com/OfficeDev/PnP-Partner-Pack/blob/master/scripts/Provision-InfrastructureSiteArtifacts.ps1 on the site collection. This will be the central hub from where all things are operated from regarding site provisioning.

Good to know libraries

PnPProvisioningTemplates

This is where your site provisioning templates are located(right in the root of the library) and all other PnP site provisioning related configuration data.

PnPProvisioningJobs

This is all of the actions(jobs, requests) for sub site, site collection, site templates etc are stored. Based on these the web jobs will start to operate.