Tim Sneed: Setting up Wormhole Sharp to Communicate with iOS Extensions

I am adding an Apple Watch app to my latest project and needed a way to communicate with the parent app on the phone. I looked at Wormhole for this type of communication, and I was happy to see that there is a port, appropriately named Wormhole Sharp. Wormhole and Wormhole Sharp use App Groups to create a way for apps to shared data via the iOS file system.

Download and build Wormhole Sharp from here and add a reference to both the parent and extension app projects.

Open the Entitlements.plist in the parent app project and select Enable App Groups. Add a new entry in the App Group section.
Do the same in the extension project and make sure to name the group the same

image of group

Apple requires naming groups by starting with ‘group’ and then using their common reverse naming style

image from apple dev site

After setting the group in both the extension, and the parent app, go and set the “Custom Entitlements” to the Entitlements.plist for both the parent and extension respectively. Do this by double clicking on the project in the solution pane.

image of entitlements

This is the most critical part, without this it will not work and you will spend a day trying to figure out what is going on.

That’s it.

Next we will learn about communicating between App Extensions and the Parent App using Wormhole Sharp. I spent way more time getting this configured to work than I did with setting up back and forth communication.

Nic Wise: Autolayout and auto-expanding UILabel

One thing I miss in iOS, which Android has, is auto expanding labels (and other views). Android has the wrap_content layout option, which works really well to flow a view.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/currency_symbol"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:textColor="@android:color/darker_gray"/>

iOS was lacking that – or so I thought. In the past, I’d had to use code to measure the size of a block of text, then set the frame and adjust other things.

var size = new NSString("Text here").StringSize(font, 9999, UILineBreakMode.CharacterWrap);
label.Frame = new CGRect(label.Frame.Origin, size);

Autolayout changes things a bit. It’s all declarative-y and designer-y, so I prefer to keep things like that inside the storyboard designer as much as possible. I recently learned how to do this, tho: the >= (or <=) constraint.

Storyboard Editor

In this case, I want the stop identifier (WW) to resize based on it’s content. It could be blank, or it could have one or 2 letters. I’m using the size of WW – about the maximum width – as the largest size, and allowing it to resize as needed. All the other constraints which are dependant on it flow from there.

The only constraint I need to manually adjust is the space between the WW and the following label (“7” in the image – “75m North West”), as I want to remove it – set it to zero – if the stop id is blank.

This works for vertical height too. Set it to be greater than or equal to the minimum height – usually one line of text, which is around 21 points – and set the number of lines to zero. The label will now take as much vertical space as needed.


This is not something which is obvious, at least it wasn’t to me, but it solves one of the big blockers I had with both Autolayout, and iOS in general – dynamic layout, especially of text.

Xamarin: Xamarin’s Got Game (Development)

If you’re new to game development, you may be wondering what framework is right for you. Luckily for C# and F# developers, Xamarin supports a wide range of powerful options like SceneKit and SpriteKit on iOS, as well as cross-platform frameworks including OpenTK, CocosSharp, and MonoGame. For developers just getting started, we recently published several […]

The post Xamarin’s Got Game (Development) appeared first on Xamarin Blog.

Xamarin: Xamarin for Students Gets Even Better with Expansion to Visual Studio

Today, we are incredibly excited to announce the expansion of our Xamarin for Students program to include support for Visual Studio, furthering our mission to make it fast, easy, and fun to build great mobile apps. Now, students get free access to everything they need to become mobile app developers virtually overnight, creating native iOS […]

The post Xamarin for Students Gets Even Better with Expansion to Visual Studio appeared first on Xamarin Blog.

Tomasz Cielecki: iOS WebView insets

I have been battling some UI constraints on iOS and I have finally found a solution to how to solve this specific problem and just wanted to share.

My problem was that I had a UIWebView, which kept laying itself out underneath the NavigationBar in my controller. A quick fix would be to just set edges for the extended layout to none like so:


However, this will make you lose the nice effect of views scrolling behind the NavigationBar, for instance if the web page you are displaying scrolls.
Enter insets. As the name kind of indicates you add some spacing into your view. There is a property called AutomaticallyAdjustsScrollViewInsets. However, for some reason it does not do anything in my case, so I had to manually adjust the inset, which I did in ViewWillLayoutSubviews as in ViewDidLoad the TopLayoutGuide is not ready yet and will give you 0 for its Length. Basically this is what I had to do:


This tells both the UIWebView’s internal ScrollView and the scroll bar that you want some space in the top equals to the height of the NavigationBar.

Daniel Hindrikes: Xamarin.Forms Android CardView

When Google introduced Material Design for Android they introduced a new view called CardView. Xamarin.Forms doesn’t have support for CardView by default but you can easily create your own view that renderers a CardView on Android. First step is to create a Xamarin.Forms control in your shared project. public class CardContentView : ContentView {   […]

Marcos Cobeña Morián: Translating Designs into Layouts: Units Conversion

One aspect that Apple pushed to the limits is the union between Designers and Developers. Instead of understanding the product development process as a chain, it is done as a very close relationship walking in the same direction. Both of them speak different languages: they use different tools during their day-to-day job, they see different … Continue reading Translating Designs into Layouts: Units Conversion

Johan Karlsson: Images in a ListView on iOS

There is an odd behavior in Xamarin Forms regarding images that are loaded from an URL and then placed in an ListView. The problem is that there is an await call when fetching images and that the image is set when that call is returned.

Since Xamarin Forms Listview now reuses cells in iOS (as it should) one small piece was overlooked. The reused cells now displays previously displayed images for a short while until the new image is downloaded.

This behavior is mitigated by a cache, so once an image is loaded it’s set instantly the next time the cell is displayed.

I’ve also filed a bug with a sample project available at https://bugzilla.xamarin.com/show_bug.cgi?id=28628 and the sample project to visualize the issue at here.

There are a number of ways around this.

Suggestion one – half-way around

This solution works, but images are blank and then suddenly pops into place. It’s visually ugly, but better than the original version  of the ImageRenderer. What is does is that it sets the Image to null (the UIImage.Image) when IsLoading changes from False to True. The problem is that is does this even when the image isn’t loading from the internet, but from the cache as well, leaving us with no option to initiate a fade in.
assembly: ExportRenderer (typeof (Image), typeof (CustomImageRenderer))]

namespace ImageListView.iOS.Renderers
{
    public class CustomImageRenderer : ImageRenderer
    {
        public CustomImageRenderer()
        {
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if ((sender as Image).IsLoading)
            {
                // The image will be reset in base if there is one already in the cache.
                // If it isnt already loaded we dont want to display the previous image
                // This is however called each time a cell comes into view so it can‘t
                // be used for opacity fading or likewise...
                // This should be handled by the code in the ImageRenderer
                Control.Image = null;
            }
           
            base.OnElementPropertyChanged(sender, e);
        }
    }
}

Suggestion two – wrap it

Wrap your image in a custom control and handle all the loading and caching yourself.

Suggestion three – rewrite it

Write your own Image-renderer from scratch to take into account when an image is fetched from the cache or not to enable a nice fade in. This is what I hope will come out of the bug report.

Suggestion four – hijack the cache

The next article is going to be about this. But simply put, we highjack the cache and control the image flow from that way. Stay tuned! 😀

Summary

I would go with suggestion one for now and wait for the outcome of the bug report.
Have a great one!