Around me

Software development for Android and iOS increases. New projects appear, old projects continue and flourish. More than ever before.

Enterprises (I’ve saw a couple of them in this situation) are this way “forced” to go from PC-only approach for employees to “accept Macs too when absolutely needed”. For iOS software development, for example, workstations or laptops, and even server side for continuous integration, must run macOS. I.e. they must be Macs.

(OK, I admit: some managers and even some artists/designers were allowed to get MacBooks already, I’ve seen them in high level meeting rooms for years, but I guess the total numbers of Mac owners in the workplace hadn’t reached “critical” values yet.)

Starting with developers and going with the trends I presume other type of employees would soon be able to obtain Mac computers at work too. Maybe the companies could eventually allow people to select their preferred type of device, just like they often allow people to have flexible schedules or choose other benefits simply to make them happy, and therefore more loyal.

(OK, again, I must admit: Linux should be a choice as well! :-))

All in order to increase work efficiency, of course.

And maybe this enterprise device diversity is going to be a good thing for the society afterall. It would be interesting to see if/when/how it would happen and what other effects it might have. (For now, we can only note that Microsoft doesn’t fear anymore of a less-Windows future: they just count on Office and the cloud, which seem to continue to sell very well, anyway.)

Advertisements
Posted in Miscellaneous | Tagged , | Leave a comment

Invariant string interpolation

shallow focus photography of keychains

Photo by Zun Zun on Pexels.com

I’m sure you like C# string interpolation support ($”{…}”):

var start = DateTime.Now;
var end = start.AddDays(7);
string weekIntervalText = $"{start}-{end}";

But you also know that this uses the current thread’s culture to format the string, so you think “Oh, my – great feature, but I cannot use it.”

However, since .NET Framework 4.6 it is possible to use a simple syntax for invariant culture based string interpolation too:

string weekIntervalText = Invariant($"{start}-{end}");

But the caveat is that you need to also add this using directive to your source code file(as actually FormattableString class defines the static Invariant method that we want to use):

using static System.FormattableString;

Enoy!

Posted in C# | Tagged , , , , | Leave a comment

Attached properties and the WPF DataGrid

bureau bureautique trombones secretariat

Photo by hermaion on Pexels.com

WPF attached properties. They look like such a difficult topic. But you only need to see a single example in action to understand their true potential: as long as your objects inherit from DependencyObject you can add as many extra properties you wish to them without any further inheritance!

Then the WPF DataGrid. It looks like such a powerful component. So easy to define columns and bind them to your item properties! But you’d only need to try to bind a column to an attached property once and you’ll understand its true potential: it can easily get really awkward!

Here below we define a DataGrid with two text columns: one it’s bound to a standard property (Value1), and another one is bound to an attached property (Value2) owned by an Attachments class in our local project.

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Value1"
      Binding="{Binding Value1}"/>
    <DataGridTextColumn Header="Value2"
      Binding="{Binding Path=(local:Attachments.Value2)}"/>
  </DataGrid.Columns>
</DataGrid>

The code behind could look like this:

var item1 = new Item { Value1 = "1" };
var item2 = new Item { Value1 = "2" };
Attachments.SetValue2(item1, "A");
Attachments.SetValue2(item2, "B");
DataContext = new { Items = new Item[] { item1, item2 } };

And the code of the other classes (Item and Attachments) is below too:

public class Item : DependencyObject
{
  public string Value1 { get; set; }
}
public static class Attachments
{
  public static readonly DependencyProperty Value2Property = 
    DependencyProperty.RegisterAttached("Value2", typeof(string), typeof(Attachments));
  public static string GetValue2(DependencyObject obj)
  {
    return (string)obj.GetValue(Value2Property);
  }
  public static void SetValue2(DependencyObject obj, string value)
  {
    obj.SetValue(Value2Property, value);
  }
}

Everything looks legit, right? (Hmm. I thought so too.)

Indeed, at runtime the app would probably look really good, exactly as expected:

Values

Moreover, if we try to update Value1 for an item, clicking on the other item afterwards to ensure the row is eventually updated (by default DataGrid only updates bound properties upon focusing out of the edited row), it works just fine.

But try the same with Value2. Oh my! It crashes! Big time!

And we can only get a hint about what happened if we look at the Output window. Otherwise it looks like a bloody null pointer exception that other code (internal WPF code, not ours) ran into!

System.Windows.Data Error: 40 : 
BindingExpression path error: 
'Value2' property not found on 'object' ''Item' (HashCode=34760343)'. 
BindingExpression:Path=Value2; 
DataItem='Item' (HashCode=34760343); 
target element is 'DataGridRow' (Name=''); 
target property is 'NoTarget' (type 'Object')

What’s that!? Ugly indeed.

Note that we did use the full syntax for the second binding: Path=(local:Attachments.Value2), so it’s not caused by anything there (confirmed by the read only mode which works very well.)

After reflecting a bit, it seems to me that by the time the two-way binding was trying to update Value2 on the current item the edit mode has already ended.

A possible workaround could be to use UpdateTriggerSource=LostFocus (or PropertyChanged) on grid column bindings. That could help also to move away from the default behavior of DataGrid and avoid waiting until the end user focuses on another grid row (or somewhere else in the app) to actually submit the values to the underlying properties.

I’d do it like this, myself:

<DataGridTextColumn Header="Value1"
  Binding="{Binding Value1, UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="Value2"
  Binding="{Binding Path=(local:Attachments.Value2), UpdateSourceTrigger=LostFocus}"/>

Maybe there are other solutions, I don’t know. I just haven’t researched enough, I admit. So if you happen to know another, better, workaround, please shoot. I.e. just post a comment below.

Posted in WPF | Tagged , , , , | Leave a comment

How to git stash from a devenv that doesn’t have it integrated

Git stash enables you to switch from one branch to another without committing changes. Still, not all environments (including Visual Studio up to 2017, at least) have it integrated.

Of course, if you’re a standard dev, the command line is your probably best friend. Still, if you prefer avoiding it for git (such as if you simply trust the UI of the devenv more than your bash skills) there is a simple alternative solution you can use.

Assuming you’re on branch1, having uncommitted changes, and you want to temporarily switch to branch2, then back, you can manage everything without git stash this way:

  • Do commit changes on local branch1, even if the code doesn’t build with your current changes; don’t worry, it’s going to be a temporary commit – you’ll eventually get rid of it, and things would go as if it never existed.
  • Do not push branch1 to any remote (to ensure the commit does remain temporary).
  • Switch to branch2, and perform all the work you want there.
  • Eventually, switch back to branch1, and soft reset the branch’s head to the commit done just before your temporary one. (In Visual Studio use View history, right click the commit shown under the temporary one, and select Reset and keep changes.)
Posted in Miscellaneous | Tagged , , , , , | Leave a comment

Embedding custom Cocoa macOS views with xibs into frameworks

close up photography of cocoa powder

Photo by Delphine Hourlay on Pexels.com

Ever thought of defining a custom Cocoa class (inheriting from NSView or a descendant), associate it with a xib to be able to define its UI with xCode designer, and then put everything into a framework that you could reuse internally or publish/sell it to others?

It should be easy, right? But if you would try it for the first time, you could easily find out that there a few major hassles to pass in order to get a proper solution.

(Disclaimer: I know there are many developers who don’t like to use xCode for designing UI, but I personally think that defining such UI declaratively using XML – do it manually if you don’t like the designer – is better than writing spaghetti code for it.)

Now back to our goal, we can reach it in a few technical steps:

  1. Create a Cocoa framework target in the xCode project, to host our custom view(s) (and link its binaries to the app).
  2. Add a View file (xib) to the new target folder, and define the UI for the control.
  3. Add a Cocoa class file to the same location, using the same filename as the .xib, inheriting from NSView or a descendant class. Make sure it’s marked as public, as it would be eventually accessed from outside the framework.
  4. Go back to the View, and select the newly added type as the File’s owner‘s class.
  5. Use xCode‘s assistant editor to show both the view and the class file on screen, and control-drag to define outlets for the important UI elements within the view’s class.
  6. In the view class, redefine initializers to load the view from the nib (binary resource generated from the xib file), and add it as a subview (!) of the custom view.
  7. In the app, use the custom view from the framework normally.

Note that I’ve not included too many technical details in the list of steps above because I’ve posted a fully working project on GitHub, defining a CustomView within a CustomViews.framework and you should be able to gather everything from there.

But still, I think we need to answer ourselves a few conceptual questions before accepting this as a technical solution. Specifically:

  1. Why does xCode allow/suggest creating a xib when we define a custom class inheriting from NSViewController, but not from NSView?
    • I think it’s just because xCode doesn’t want to go through the subview approach proposed above, while a controller could easily work together with a (default) view.
    • Note that even if you’d create a NSViewController with an associated xib for the UI through xCode, it would work only within the app’s module – from a framework it would give an error at loading because the xib won’t be found within the app’s main (“null”) bundle!
  2. Is it OK to actually have the view loaded from xib as a subview of the custom view?
    • It doesn’t feel like an ideal solution but technically it works and I didn’t find any caveats yet. And (in my opinion) this is better than creating all the UI internals from code alone.

Finally, a small heads-up: the solution described above could partially (or entirely) apply to developing CocoaTouch views too, but it would probably require a few more steps. Still, for iOS development you can usually find more articles on the Web already, so I haven’t prepared anything myself on that side (yet). But, to address this at least with a link – if you’re on that thread, you can check this post instead.

Update: To support @IBDesignable and as well as a possible performance improvement, you should also ensure that your NSView-based class sets canDrawSubviewsIntoLayer to true. (I’ve modified the GitHub repo’ source code accordingly.)

Posted in macOS | Tagged , , , , , | Leave a comment

“Local” git repo remote on iCloud

boy child clouds kid

Photo by Porapak Apichodilok on Pexels.com

Disappointingly, Apple doesn’t (yet?) have cloud based git repo hosting (and it seems even xCode server which previously could have allowed teams to host repos on macOS Server doesn’t offer this anymore, either – maybe awaiting for code integration features offered by a third party company that they have recently purchased.)

Of course, teams that aren’t afraid to push code to somebody else’s server (i.e. the cloud) can use a third party service like GitHub (which supports private repos for a fee), Bitbucket (which brings private repos for free!), or even Visual Studio Team Services (e.g. if they already use it for .NET projects.) While others could simply choose to host their own git server instances (which they can get for free, even open sourced).

On the other hand, if you are a single developer and would like to use git in xCode mostly for source backup purposes and to obtain some extra local code control (for your macOS/iOS projects) rather than for sharing anything with others, you might just want a repo without a remote. That simple git initialization and then standard git commit, push, and branching are offered by xCode as built-in features.

Sure, however, you cannot stop here: what would happen with your source code database in case your Mac breaks (or anything like this)? You think: since you’d (probably) deploy your apps through Apple means (i.e. their App Stores) you’d be forced to trust them at least for delivering binaries, so why not also having remote project repos on your iCloud drive? Sure, this is still going to need “somebody else’s” server, but at least it will be one of a second – not third – party!

If you reach the same conclusion and want to have a bare git repo on iCloud, I would suggest following this post – it lists all the required steps, and it works well.

But I need to add, tough, that to have full xCode integration (at least with the current development environment version) you need to ensure these steps are not missed nor replaced (I tried that “I know better” approach myself):

  • Do create a symbolic link your iCloud drive’s local folder – or to the repos folder inside it – otherwise a space in the file path would generate issues in xCode (while plain git commands would still work in a Terminal window, either by escaping the space or by quote enclosing).
  • Do add the remote (which can be named origin – that works!) from a Terminal window, even if xCode has an Add remote feature itself (with UI), because otherwise things would break deeply (for an unknown reason, probably related to the file path not being correctly considered as an URL by xCode itself at the time of adding it).

Finally, a heads-up: if you’d ever want to live-share the remote with others you won’t be able to (unless Apple changes their iCloud sharing philosophy): currently cloud drive folders cannot be shared with others (except as zipped content actually sent to them, just like with standard files).

Posted in iOS, macOS, Swift | Tagged , , , , , , , | 1 Comment

Afraid of AI?

colorful color play concentration

Photo by Pixabay on Pexels.com

OK (or not OK). But (anyway) you shouldn’t be afraid of AI programming.

This post, written by one of the best young programmers I’ve ever worked with (he has just started to blog – good luck Zoli!), mentions that there is a lot of misunderstanding about what AI is at its core, and what are its conceptual limits.

The essay mentions – as possibly you would otherwise realize only if you’d go away from all advertising and do some Python yourself – that AI is not the solution for every problem, being just a practical way to get some of the things, here and there, done – and lists the advantages and disadvantages of deep learning in a very objective manner (but of course, take this with a fair dose of subjectivity from my side :-)).

Sure, to do AI programming one would better be able to understand maths and statistics, and in the future maybe also some physics (going towards quantum computing), but essentially it’s not that hard and, with reasonable time spent on learning and practicing, any programmer that would do this out of love could do AI and get paid well for it!

Posted in Development | Tagged , | 1 Comment