Sunday, July 27, 2014

Understanding IBOutlet and IBAction in InterfaceBuider

In XCode interface builder, when adding a UI element in storyboard, it only creates an UI element, for example UITableView or UILabel, or UIViewController, and it does not give the element reference to be accessed by external module.

However, each of these class can define property, method and IBOutlet & IBAction for external access. Actually, the IBOutlet is just a regular property, the only extra thing IBOutlet does is telling Interface Builder that this property is available to associate with other instance within the current uiViewController scope at design time, so developer can make the association easily in interface builder between IBOutlet and other elements.

So IBOutlet is only meaningful within InterfaceBuilder's UIViewController context so as to allow design time association. Similarly, the Referencing outlet shows the current UI element instance is referenced by all other instances' outlet property.

Note, you can add any object into interface builder, and they will be allocated at runtime by interface builder, and any IBOutlet can associate with those arbitrary object, even if they are nothing to do with UIView. 

Tuesday, July 22, 2014

Property, and its instance variable, accessors with ARC

Before ARC, directly access instance variables will not affect the object's references—it did not extend the lifetime of the object. If the instance variable is associated with a property, then the property should be used to access the object, so that the reference can be properly managed based on property reference attribute (strong, weak, etc).

With ARC, instance variables are strong references by default—assigning an object to an instance variable directly will extend the lifetime of the object, unless the instance variable has __weak attribute. 


By default, a readwrite property will be backed by an instance variable, which will again be synthesized automatically by the compiler. Unless you specify otherwise, the synthesized instance variable has the same name as the property, but with an underscore prefix. For a property called firstName, for example, the synthesized instance variable will be called _firstName.

By default, the property's accessor methods are synthesized automatically by the compiler.
The synthesized methods follow specific naming conventions:
  • The method used to access the value (the getter method) has the same name as the property.
    The getter method for a property called firstName will also be called firstName.
  • The method used to set the value (the setter method) starts with the word “set” and then uses the capitalized property name.
    The setter method for a property called firstName will be called setFirstName:.

Override and overload in objective C

Objective C is message based and it has the full support on override. So if a method with the same signature is implemented in both the super class and derived class, calling the method will invoke the implementation in the derived class.

The object c does not support overload, so you cannot define or implement method with the same method name and parameter name but different return types or parameter types. The reason is objective C uses selector to distinguish different method, and select only use the information of method name and parameter name, and ignore the type information, for example, NSSelectorFromString method will only take method name and parameter name as input without parameter type information.

As a result, if a class has method only methods only different from parameter types, they will be regarded as the same method. This can particularly cause problem if the two methods are defined in super and derived class separately.

Automatically select client certificate by Chrome on Mac

Two steps are required to automatically select client certificate without user interaction.
1. trust the certificate:
open keychain utility and select the client certificate, open the certificate detail by double click it. Open trust section,  in "When using this certificate" dropdown list box, select "Always trust"

2. automatically pick the certificate
create or edit file "/Library/Preferences/com.google.Chrome.plist" and insert code similar to below sample code to match the client certificate information based on the host url pattern information:

<plist version="1.0">
<dict>
  <key>AutoSelectCertificateForUrls</key>
   <array>
     <string>{"pattern":"[*.]sap.corp","filter":{"ISSUER":{"CN":"SSO_CA"}}}</string>
     <string>{"pattern":"[*.]sap.com","filter":{"ISSUER":{"CN":"SSO_CA"}}}</string>
     <string>{"pattern":"[*.]sap-ag.de","filter":{"ISSUER":{"CN":"SSO_CA"}}}</string>
   </array>
</dict>
</plist>

Friday, May 30, 2014

User gem behind proxy on MAC

1. To use gem command on mac behind proxy, set --http-proxy option
gem install --http-proxy http://corporate-proxy:1234 <gem_name>

2. To update gem
sudo gem update --http-proxy http://proxy:8080 --system 

Sunday, May 25, 2014

Create oData service provider with WCF data service with visual studio 2015

The following steps are used to create oData provider with MS WCF data service

Required software:
SQL server 2012~2014
Visual Studio 2015


1. Create Sample NorthWind database in SQL 2012
   1.1 download Northwind  database from the below link and install
http://www.microsoft.com/en-us/download/details.aspx?id=23654

   1.2 open sql server 2012, open file instnwnd.sql, replace following two lines
exec sp_dboption 'Northwind','trunc. log on chkpt.','true'
exec sp_dboption 'Northwind','select into/bulkcopy','true'
 
with the new line  
ALTER DATABASE Northwind SET RECOVERY SIMPLE
 
  1.3 execute the script and verify the northwind database is created.
 
 
2. Create Data model
  2.0 Create ASP.Net web empty project in VS2015
 
  2.1 right click the solution and select Add new Item, select Data, and ADO.Net entity Data model, named it as Northwind.edmx
  2.2 select EF Designer from Database, and choose Northwind database from SQL Server 2012
  2.3 select Entity Framework 6.x
  2.4 select the checkbox of all tables , deselect views and store procedures
 
3. Create WCF data service
  3.1 right click the solution and select manger NuGet package menu
  3.2 Right-click the project and choose Manage NuGet Packages. From the Manage NuGet Packages dialog, make sure Include Prerelease is selected in the top dropdown box. Search for “Microsoft.OData.EntityFrameworkProvider” and install it.
  3.3 Add new item from Web->WCF Data service 5.6.4, name it as Northwind.svc

  3.2 in Northwind.svc.cs, replace the comment /* TODO: put your data source class name here */ to  
System.Data.Services.Providers.EntityFrameworkDataService< NorthwindEntities >
 
 3.3 Add following lines in InitializeService method
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
          
3.4 select Northwind.svc as starting page and F5 to start the app in IE with URL of 
http://localhost:54108/Northwind.svc/Customers('ALFKI')/Orders?$filter=OrderID eq 10643
The port port 54108 may be different  
3.5 For windows8 and iis 8, you also need to enable ".NET Framework 4.5 Advanced Service" from control panel's Turn Windows Features on or off to allow query on .svc
 
4. Create client application
   4.1 create a .net form applicaton
   4.2 select "view" "Other Windows, Data Source" and select service type to add northwind service as NorthwindClient
   4.3 add a datagridview control and a button, when button is clicked, run the below code
                NorthwindEntities context = new NorthwindEntities(new Uri("http://localhost:54108/Northwind.svc/"));
                context.IgnoreMissingProperties = true;
                var customer = context.Customers.ToList();
                dataGridView1.DataSource = customer; 
   4.4 run the app and click the button to show the customer list
   4.5 Add two textbox for user to input new customer name and id
   4.5 Add a button of "New" to create new customer with the following code
           NorthwindEntities context = new NorthwindEntities(new Uri("http://localhost:54108/Northwind.svc/"));

            context.AddToCustomers(new Customer() { CustomerID = txtID.Text.Trim(), CompanyName = txtName.Text.Trim() });
            context.SaveChanges();
   4.6 get a id and name, click new button, the customer should be added into database
   4.7 add a button of update to update the company name with the below code
             string customerId = txtID.Text.Trim();
             NorthwindEntities context = new NorthwindEntities(new Uri("http://localhost:54108/Northwind.svc/")); 
            var customerToChange = (from customer in context.Customers
                                    where customer.CustomerID == customerId
                                    select customer).Single();
          
            customerToChange.CompanyName = txtName.Text.Trim();
            customerToChange.ContactName = txtName.Text.Trim();

            context.UpdateObject(customerToChange);
             context.SaveChanges();
   4.8 add a button to delete a customer
     string customerId = txtID.Text.Trim();             
            NorthwindEntities context = new NorthwindEntities(new Uri("http://localhost:54108/Northwind.svc/")); 
            var customerToChange = (from customer in context.Customers
                                    where customer.CustomerID == customerId
                                    select customer).Single();
          
           
            context.DeleteObject(customerToChange);
             context.SaveChanges();

Monday, May 19, 2014

ios setCookieAcceptPolicy not shared by apps

In apple document for NSHTTPCookieStorage setCookieAcceptPolicy,  it says "The default cookie accept policy is NSHTTPCookieAcceptPolicyAlways. Changing the cookie policy affects all currently running applications using the cookie storage.". 
The test shows that is not the case, changing the cookie policy in one app will not affect other apps running on the same device.