Monday, July 4, 2016

Running the Angular 2 Quickstart tutorial in Visual Studio Code on Mac OS

In this post I will go through the steps that I took in order to complete the Angular 2 Quickstart tutorial (with Typescript) using Visual Studio Code on Mac OS. The versions for the software are as follows:

  • VS Code: 1.2.1
  • Mac OS: 10.11.5 (El Capitan)
The Angular 2 quickstart can be found at this link: https://angular.io/docs/ts/latest/quickstart.html.

We start by creating a new solution, which in VS Code is opening a folder. In the tutorial they named the folder angular2-quickstart. It doesn't really matter, so just make a new folder.

After this we need to follow the next few steps in order to have the solution up and running in VS Code.

1. Compiling the Typescript code to Javascript.

Open Command Palette with ⇧⌘P (or View -> Command Palette) and start typing Configure Task Runner.
Then, select Tasks: Configure Task Runner and you will get the next list:

From here you need to select TypeScript - tsconfig.json. This will create a tsconfig.json under the .vscode folder.


2. Installing NodeJs and npm (if you don't already have it).

This tutorial states that you need to have at least version 5.x.x for NodeJs and 3.x.x for npm. To check if you have the required version, open a terminal window (or the Integrated Terminal in VS Code) and type node -v for NodeJs and npm -v for npm.

From here on I have followed the steps in the tutorial. 

In order to be able to run the application from VS Code a few additional steps are required:

1. Click on the Debug icon on the left side.

2. Click on the cog icon and select NodeJs from the list. This will create a file called launch.json under the .vscode folder.
Note: if you click the cog icon again, nothing will happen. If you want to see the available options again, delete the launch.json file.

3. In the launch.json file, edit the program property so that it looks like this: ${workspaceRoot}/node_modules/lite-server/bin/lite-server

4. Click on the start icon and the application should start.

Wednesday, August 26, 2015

Integrating Swift with Objective C

I started to implement the new design for Jano (Japano) and I decided to do some small refactoring of the code.

In the Achievements screen I am displaying a list of levels that the user can achieve by taking tests in a UIScrollView. It's a maximum of 4 levels and each of the views needs to have a background image.

Initially I subclassed UITableViewCell and I wrote the code inside the class for the arranging of the GUI elements.
Now I want to use another class that will take care of the GUI only. I will do this using Swift and in this post I will write about how to combine the two types of files.

First thing, add a new file from the menu File - New - File and select Swift File. After naming it, Xcode will ask you if you want to add bridging header. Click Yes.

I have named the class LevelCellInterfaceTool. By default the class is not public, so I had to modify the access level of the class to public:


public class LevelsCellInterfaceTool: NSObject {

}
Inside the class I then created a public method (func) that just shows a simple UIAlertView:

public class LevelsCellInterfaceTool: NSObject {
public func ShowSimpleMessage()
    {
        let message = "This is a UIAlerView declared in Swift!"
        let v = UIAlertView(title: "Swift UIAlertView", message: message, delegate: nil, cancelButtonTitle: "Ok")
        v.show()
    }

}
The next challenge was to call ShowSimpleMessage from a class declared in an Objective C file (.h and .m). This was accomplished in 3 simple steps:

1. Forward declare LevelCellInterfaceTool in the interface file (.h) of the class that needs it: 
@class LevelsCellInterfaceTool;

@interface LevelsListCellTableViewCell : UITableViewCell

{
        
}

@end

2. In the implementation file (.m) use an #import directive for all the classes declared with Swift. In the official documentation it is saying to use a particular naming convention: ProductModuleName-Swfit.h.
In my case, ProductModuleName is the name of the project. So, it becomes Jano-Swift.h:

#import "LevelsListCellTableViewCell.h"
#import "Jano-Swift.h"

@implementation LevelsListCellTableViewCell
...
@end

3. Calling the method.
After writing a new method (func) in the Swift class it is necessary to first build the project so that the Objective-C class sees it (at least in Xcode 6.3.2).
Somewhere in the class instantiate the Swift class as you would with a regular Objective-C class:

LevelsCellInterfaceTool *guiTool = [[LevelsCellInterfaceTool alloc] init];
        [guiTool ShowMessage];
        [guiTool release];

Wednesday, September 17, 2014

How to install a Windows service from the command prompt

Installing a Windows service from the command prompt is a fairly simple task, only a few steps to follow.


  1. Build the project in Release mode
  2. Go to the Release folder and copy the full address from the address bar
  3. Open Visual Studio Command Prompt (On Windows 7 you can find it under Start - All programs - Visual Studio - Visual Studio Tools; on Windows 8 click start and start typing Visual Studio Command Prompt )*
  4. Install the service using the command installUtil and passing the path you copied at step 2: installUtil pathToFolder

If the service is already installed you will need to uninstall it first:
installUtil /u pathToFolder

*If on the machine where you need to install it you don't have Visual Studio, you will have to find the executable installUtil. On my Windows 8 (but I believe it is the same on Windows 7) it is in C:\Windows\Microsoft.NET\Framework\v4.0.30319


Monday, September 8, 2014

Creating a custom setter and getter for a property in Objective C


When creating the mobile application Jano I had to show different statistics in a special menu. It had to appear in a label (of course) and I wanted to format it according to the phone's style.

The best solution for me was to add a string property to the model that would return the NSNumber property formatted accordingly.

In the .h file I defined the public properties as follows:


@property (nonatomic, strong) NSString *ValueAsString;

@property (nonatomic, strong) NSNumber *Value;


In the .m file, the code appear like this:
@synthesize Value = _value, ValueAsString = _valueAsString; 


//Getter for ValueAsString
-(NSString*) ValueAsString
{
NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setGroupingSeparator:[[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator]];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString *result = [formatter stringFromNumber:_value];

    return result;
}

-(void)setValueAsString:(NSString*)value
{
_valueAsString = value;
}
Although I had no use for the setter, I added it here so that it would be a full example.

Thursday, August 28, 2014

JavaScript runtime error: Unable to get property 'call' of undefined or null reference

I got this error after I had installed a NuGet package with editor templates for Bootstrap for ASP.NET MVC 5.

The solution consisted of 2 steps:
First, install package JQuery Migrate. Second, edit the method RegisterBundles in class BundleConfig from App_Start folder and change the part where it adds the bundle jqueryval.

Initially, in my project, it looked like this:

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                          "~/Scripts/jquery.validate*"
                        ));


Here you have to add a line to include the jquery-migrate files:

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery-migrate*",
                        "~/Scripts/jquery.validate*"
                        ));



Monday, July 21, 2014

Could not load file or assembly 'WebGrease, Version=1.5.1.25624, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies

I was working on a MVC 5 project in Visual Studio 2013, and I was getting the error in the title everytime I was trying to run the project. We were using Visual SVN for the versioning and I was the only one in my team that had this problem.

The only thing that worked for me was this:
  1. Uninstall Microsoft.AspNet.Web.Optimization
  2. In Nuget command prompt run: install-package Microsoft.AspNet.Web.Optimization -Version 1.0.0

This will install an older version of Web.Optimization. The project was initially referencing version 1.1.0. The problem is not with WebGrease, but with the System.Web.Optimization.dll that is referencing an old, inexisting version of WebGrease.

When I ran the project, it worked, but I wanted to use the same package version as the rest of team. So, I tried to update but... the error returned...

After this, I deleted the project (again) and took it back from the SVN. To my surprize, it started to work... The thing is that I had deleted the project completely and took it from the SVN several times before this. I even took the dlls from a colleague because I thought that maybe I'm getting corrupted files from NuGet, but to no avail.

Strange...

Thursday, July 17, 2014

UITableViewCell with UIScrollView inside

When I started coding in Objective C I had some hard times learning how to create a UITableView application. Luckily things changed over time :).

I decided to create a small sample application that shows how to add a table view to a view controller. This table view has only 2 sections, each with one custom created UITableViewCell.

The project is hosted on GitHub, here.

Structure

The AppDelegate launches the ListsTableViewController, a UIViewController that implements UITableViewDelegate and UITableViewDataSource. In the controller I have implemented only some of the methods from the protocols.

I usually use a second class to add the interface elements to my view controllers. In this case, the class is called ListsTVCInterfaceTool. It has a private property of type ListsTableViewController a method called AddTableView.

Below I have listed the code for the ListsTVCInterfaceTool.h:


#import <Foundation/Foundation.h> 
#import "ListsTableViewController.h" 

@class ListsTableViewController; 
@interface ListsTVCInterfaceTool : NSObject 

@property ListsTableViewController *controller; 

//making sure that it will be used only for the ListsTableViewController 
-(id)initWithController:(ListsTableViewController*) controller; 

//Used to add the table view to the controller 
-(void)AddTableView; 

@end
I could have added a parameter of type ListsTableViewController to the AddTableView method, but I preferred to make it a private property so that if we want to add other interface elements with different methods, we don't have to specify the same parameter everywhere. We just init the class once and pass the controller to it.

Since also the view controller will have a reference to this class I have used the @class directive to avoid a circular dependency.

The code for the ListsTVCInterfaceTool.m looks like this:

-(id)initWithController:(ListsTableViewController *)controller 

{ 

self = [super init]; 

if (self) { 

_controller = controller; 

} 

return self; 

} 



-(void)AddTableView 

{ 

CGFloat width = 0; 

CGFloat height = 0; 

width = [[UIScreen mainScreen] bounds].size.width; 

height = [[UIScreen mainScreen] bounds].size.height; 



CGRect rect = CGRectMake(0, 0, width, height); 

_controller.tableView = [[UITableView alloc] initWithFrame:rect]; 

[_controller.tableView setTableFooterView:[[UIView alloc] initWithFrame:CGRectZero]]; 

[_controller.view addSubview:_controller.tableView]; 

_controller.tableView.dataSource = _controller; 

_controller.tableView.delegate = _controller; 

[_controller.tableView setUserInteractionEnabled:YES];   



} 



Some things to notice here:

[_controller.tableView setTableFooterView:[[UIView alloc] initWithFrame:CGRectZero]];

The above line will tell the table view to display only a number of rows equal to the rows in the datasource.  If this line is commented out we would see in the table view more than 2 lines, because it will try to fill the empty space with "fake" rows. I say fake, because they are there only to fill the gap between the last row from the datasource and lower bounds of the view.

_controller.tableView.dataSource = _controller; 
_controller.tableView.delegate = _controller;

The 2 lines of code will set the ListsTableViewController as the delegate and the datasource for the tableview.

Now that we saw what the interface tool class looks like, let's get back to the UITableViewController, the ListsTableViewController.

The code for the ListsTableViewController.m file is this:



- (void)viewDidLoad

{

[super viewDidLoad];



[_tableView registerClass:[AnimalListTableViewCell class] forCellReuseIdentifier:CELL_IDENTIFIER_ANIMAL];



[_tableView registerClass:[CarListTableViewCell class] forCellReuseIdentifier:CELL_IDENTIFIER_CAR];





ListsTVCInterfaceTool *interfaceTool = [[ListsTVCInterfaceTool alloc] initWithController:self];

[interfaceTool AddTableView];

}





#pragma mark - Table view data source



- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

{

// Return the number of sections.

return 2;

}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

// Return the number of rows in the section.

return 1;

}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{



UITableViewCell *cell = nil;

if (indexPath.section == 0) {

cell = [tableView dequeueReusableCellWithIdentifier:CELL_IDENTIFIER_CAR];

}

else if (indexPath.section == 1)

{

cell = [tableView dequeueReusableCellWithIdentifier:CELL_IDENTIFIER_ANIMAL];

}



if (!cell) {

if (indexPath.section == 0) {

cell = [[CarListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELL_IDENTIFIER_CAR];

}

else if (indexPath.section == 1)

{

cell = [[AnimalListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELL_IDENTIFIER_ANIMAL];

}

}

return cell;



}



-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

return TABLEVIEW_CELL_HEIGHT;

}
The ViewDidLoad method registers the 2 custom cells and calls the method to add the table view to the controller.
In the cellForRowAtIndexPath method I display one cell type or the other, depending on the section I am in.

All the upper case strings here are constants defined in the Constants file.

Let's take a look at the CarListTableViewCell.m file:


@implementation CarListTableViewCell
@synthesize ScrollView = _ScrollView;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {

        // Initialization code
ListManager *manager = [[ListManager alloc] init];
models = [manager GetCars];

        [self arrangeInterface];
}

    return self;
}


#pragma mark - Interface elements

-(void)arrangeInterface
{

    CGFloat width = self.frame.size.width * [models count];
CGFloat height = TABLEVIEW_CELL_HEIGHT;

    _ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, height)];
_ScrollView.delegate = self;
_ScrollView.indicatorStyle = UIScrollViewIndicatorStyleBlack;
_ScrollView.alwaysBounceHorizontal = YES;
[_ScrollView setUserInteractionEnabled:YES];
_ScrollView.scrollEnabled = YES;
_ScrollView.pagingEnabled = YES;

    _ScrollView.contentSize = CGSizeMake(width, height);


    for (int i = 0; i < [models count]; i++) {
CarModel *model = (CarModel*)[models objectAtIndex:i];
[self GetViewFromModel:model andIndexOnScrollView:i];

    }

    [self.contentView addSubview:_ScrollView];

}


-(void)GetViewFromModel:(CarModel*)model andIndexOnScrollView:(int)index
{

    CGFloat width = self.frame.size.width;
CGFloat height = _ScrollView.frame.size.height;
CGFloat x =  width * index;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, 0, width, height)];

    NSArray *colors = [NSArray arrayWithObjects:[UIColor orangeColor], [UIColor greenColor], [UIColor blueColor],[UIColor redColor], nil];

    view.backgroundColor = (UIColor*)[colors objectAtIndex:index];

    [self AddElementsToView:view fromModel:model];
[_ScrollView addSubview: view];
}


#pragma mark - Labels

-(void)AddElementsToView:(UIView*)view fromModel:(CarModel*)model
{

    [self AddBrandLabelToView:view fromModel:model];
[self AddModelLabelToView:view fromModel:model];
[self AddYearLabelToView:view fromModel:model];

}
In the constructor I load the models array from the manager. The method to populate the array brings 3 objects of type CarModel.
Next, I arrange the interface. I first setup the UIScrollView and add to it 3 views, each with the details of the corresponding model.

The project is hosted on GitHub, here.