Objective C: UITextField controlling background image/color

If you set
UITextField *tf = [[UITextField alloc] init];
tf.borderStyle = UITextBorderStyleRoundedRect;
you can't control background of text field. To controlling background you need
#import "QuartzCore/QuartzCore.h"
...

UITextField *tf = [[UITextField alloc] init];
tf.borderStyle = UITextBorderStyleDefault;
tf.background = [UIImage imageNamed:@"bg_000000_20.png"];
tf.layer.cornerRadius = 5.0;
tf.layer.masksToBounds = YES;

// for vertical align
tf.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

// for border
tf.layer.borderWidth = 1.0;
tf.layer.borderColor = [[UIColor darkGrayColor] CGColor];

// for left padding
tf.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
tf.leftViewMode = UITextFieldViewModeAlways;

Java: Read key from Windows Registry.

After create new windows registry in cmd by:
reg add HKLM\SOFTWARE\Policies\MyApplication\AES /v SecurityKey /d 12345678901234567890123456789012
need read it from java
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;

public class WindowsReqistry {

    /**
     * 
     * @param location path in the registry
     * @param key registry key
     * @return registry value or null if not found
     */
    public static final String readRegistry(String location, String key){
        try {
            // Run reg query, then read output with StreamReader (internal class)
            Process process = Runtime.getRuntime().exec("reg query " + 
                    '"'+ location + "\" /v " + key);

            StreamReader reader = new StreamReader(process.getInputStream());
            reader.start();
            process.waitFor();
            reader.join();

            // Parse out the value
            String[] parsed = reader.getResult().split("\\s+");
            if (parsed.length > 1) {
                return parsed[parsed.length-1];
            }
        } catch (Exception e) {}

        return null;
    }

    static class StreamReader extends Thread {
        private InputStream is;
        private StringWriter sw= new StringWriter();

        public StreamReader(InputStream is) {
            this.is = is;
        }

        public void run() {
            try {
                int c;
                while ((c = is.read()) != -1)
                    sw.write(c);
            } catch (IOException e) { 
            }
        }

        public String getResult() {
            return sw.toString();
        }
    }
    public static void main(String[] args) {

        // Sample usage
        String value = WindowsReqistry.readRegistry("HKLM\\SOFTWARE\\Policies\\MyApplication\\AES", "SecurityKey");
        System.out.println(value);
    }
}

Android: Import SSL certificate and use it to SSL connection


  1. First of all you need get SSL certificate. You can obtain certificate (file with .cer extention) from the chain included in the endpoint certificate or from the official site of the issuer (in the Base64 encoded X.509 format).

    Or if you have this certificate installed on you local computer you can obtain it by run "mmc" (Microsoft Management Console) from command line ("Prompt" or "Run"). If you don't have Certificate snap-in go to  File -> Add/Remove Snap-in... -> Select from available snap-ins "Certificates" -> Add to Selected snap-ins -> Ok.

    Find certificate what do you need -> Right click -> All Tasks -> Export -> Select Base-64 encoded X.509 (.CER) -> Save into my_certificate.cer in my_certificate_path place.

    Content of this file look like:
    -----BEGIN CERTIFICATE-----
    MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0B...
    -----END CERTIFICATE-----
    
  2. For create the keystore download latest release of Bouncy Castle provider (bcprov-jdkxx-xxx.jar) and store it in provider_path place. You must have JRE installation for invoke keytool (located under bin folder). You may add path to keytool into CLASSPATH environment variable or use absolute path.
  3. Execute this command for create mykeystore.bks (don't use upper case and "_" for name):
    D:/PROGRA~1/Java/jre7/bin/keytool -importcert -v -trustcacerts -file "my_certificate_pathmy_certificate.cer" -alias myAlias -keystore "my_keystore_path/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "provider_path/bcprov-jdkxx-xxx.jar" -storetype BKS -storepass "my_password"
    
  4. You may verify if the certificate was imported correctly
    D:/PROGRA~1/Java/jre7/bin/keytool -list -keystore "my_keystore_path/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "provider_path/bcprov-jdkxx-xxx.jar" -storetype BKS -storepass "my_password"
    
  5. Paste you mykeystore.bks as a raw resource under res/raw (this generate R.raw.mykeystore resource)
  6. Create a custom HttpClient to use you SSL certificate for HTTPS connection:
    import java.io.InputStream;
    import java.security.KeyStore;
    
    import org.apache.http.conn.ClientConnectionManager;
    import org.apache.http.conn.scheme.PlainSocketFactory;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.SingleClientConnManager;
    
    import android.content.Context;
    
    public class MyHttpsClient extends DefaultHttpClient {
      
        final Context context;
     
        public MyHttpsClient(Context context) {
            this.context = context;
        }
     
        @Override
        protected ClientConnectionManager createClientConnectionManager() {
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            // Register for port 443 our SSLSocketFactory with our keystore
            // to the ConnectionManager
            registry.register(new Scheme("https", newSslSocketFactory(), 443));
            return new SingleClientConnManager(getParams(), registry);
        }
     
        private SSLSocketFactory newSslSocketFactory() {
            try {
                // Get an instance of the Bouncy Castle KeyStore format
                KeyStore trusted = KeyStore.getInstance("BKS");
                // Get the raw resource, which contains the keystore with
                // your trusted certificates (root and any intermediate certs)
                InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
                try {
                    // Initialize the keystore with the provided trusted certificates
                    // Also provide the password of the keystore
                    trusted.load(in, "my_password".toCharArray());
                } finally {
                    in.close();
                }
                // Pass the keystore to the SSLSocketFactory. The factory is responsible
                // for the verification of the server certificate.
                SSLSocketFactory sf = new SSLSocketFactory(trusted);
                // Hostname verification from certificate
                // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
                sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
                return sf;
            } catch (Exception e) {
                throw new AssertionError(e);
            }
        }
    }
    
  7. Use you custom HttpClient:
    DefaultHttpClient client = new MyHttpsClient(getApplicationContext());
    

Objective C: Detect start of bouncing effect for UIScrollView

For detect bouncing of UIScrollView (or UITableView ...) using UIScrollViewDelegate:
static BOOL _draggingView = NO;

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
 _draggingView = YES;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
 _draggingView = NO;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
 NSInteger pullingDetectFrom = 50;
 if (self.contentOffset.y < -pullingDetectFrom) {
  _draggingView = NO;
  NSLog(@"Pull Down");
 } else if (self.contentSize.height <= self.frame.size.height && self.contentOffset.y > pullingDetectFrom) {
  _draggingView = NO;
  NSLog(@"Pull Up");
 } else if (self.contentSize.height > self.frame.size.height && 
       self.contentSize.height-self.frame.size.height-self.contentOffset.y < -pullingDetectFrom) {
  _draggingView = NO;
  NSLog(@"Pull Up");
 }
}

Objective C: Sort array of objects

If we have array of some objects:
@interface SimpleObject : NSObject {
 NSInteger key;
 NSString *name;
        . . .
}
and we need to sort this array by "name" property of SimpleObject. Use NSSortDescriptor:
// declare array with SimpleObject instances
self.simpleObjectsArray = . . .

NSSortDescriptor *sortDescriptor =
        [[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES] autorelease];
NSArray *sortDescriptors = 
        [NSArray arrayWithObject:sortDescriptor];
// array contained all instances sorted by "name" field
NSArray *sortedArray = 
        [self.simpleObjectsArray sortedArrayUsingDescriptors:sortDescriptors];

Objective C: Bring back user to your application during/after he End the Call

Sometime you need come back to application after phone call initiated by your own application.
Exist two options (each from them not 100% that do you want), but if no choice..

  1. After starting phone call you getting local notification alert with two option
    • Cancel (stay on call screen)
    • Return (back to application during your call)
    NSURL *phoneSchemaURL = [NSURL URLWithString:@"tel://123456789"];
     
    [[UIApplication sharedApplication] openURL:phoneSchemaURL];
    
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    if (localNotification != nil) {
     NSDate *notificationDate = [[NSDate alloc] initWithTimeIntervalSinceNow: 3];
      
     localNotification.fireDate = notificationDate;
     [notificationDate release];
      
     localNotification.alertBody = @"Stay in app";
     localNotification.alertAction = @"Return";
      
     localNotification.soundName = UILocalNotificationDefaultSoundName;
      
     [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    }
    [localNotification release];
    
  2. After ending phone call your application retrieve focus.
    NSURL *phoneSchemaURL = [NSURL URLWithString:@"tel://123456789"];
     
     NSString *osVersion = [[UIDevice currentDevice] systemVersion];
     
    if([osVersion compare: @"3.1" options: NSNumericSearch] >= NSOrderedSame ) {
     UIWebView *webview = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
     //or if you just want to call and back to application
     //UIWebView *webview = [[UIWebView alloc] init];
    
     [webview loadRequest:[NSURLRequest requestWithURL:phoneSchemaURL]];
      
     //if you just want to call and back to application remark code below, but don't forget release webview
     [self.view addSubview:webview];
     [webview release];
    } else {
     // On 3.0 and below, dial as usual
     [[UIApplication sharedApplication] openURL: phoneSchemaURL];          
    }
    

Objective C: Basic HTTP Authorization


  1.  First version of "Authorization":
    NSString *loginString = [NSString stringWithFormat:@"%@:%@", [self userName], [self password]];
    NSString *encodedLoginData = [Base64 encode:[loginString dataUsingEncoding:NSUTF8StringEncoding]];  
    NSString *base64LoginData = [NSString stringWithFormat:@"Basic %@",encodedLoginData];
    
    NSURL *url=[NSURL URLWithString:@"http://my_url.com"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                    timeoutInterval:10.0];
    
    [request setHTTPMethod:@"POST"];
    
    [request setValue:base64LoginData forHTTPHeaderField:@"Authorization"];
    
    NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    
  2. Second version of "Authorization":
    NSURL *URL = [NSURL URLWithString:url];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL
                                             cachePolicy:NSURLRequestUseProtocolCachePolicy
                                         timeoutInterval:10.0];
    
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    
    NSURLConnection Delegates
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
        if ([challenge previousFailureCount] == 0) {
            NSLog(@"received authentication challenge");
            NSURLCredential *newCredential = [NSURLCredential credentialWithUser:@"USER"
                                                                        password:@"PASSWORD"
                                                                     persistence:NSURLCredentialPersistenceForSession];
            NSLog(@"credential created");
            [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
            NSLog(@"responded to authentication challenge");    
        }
        else {
            NSLog(@"previous authentication failure");
        }
    }
    

Objective C: Change title of back button in navigation bar

You need change title of the back button from view controller which call to next view controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (self.detailsViewController == nil) {
        self.detailsViewController = [[DetailsViewController alloc] initWithNibName:@"DetailsViewController" bundle:nil];
 }
 
 [self.navigationController pushViewController:detailsViewController animated:YES];
 
 [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (void)viewDidLoad {
 self.title = NSLocalizedString(@"root_tab_title_0", @"My Title");

 //Set title for back button to this controller
 self.navigationItem.backBarButtonItem =
  [[[UIBarButtonItem alloc] initWithTitle:@"My back button"
      style:UIBarButtonItemStyleBordered
      target:nil
      action:nil] autorelease];
}

Objective C: Change title font in navigation bar

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
label.textAlignment = UITextAlignmentCenter;
label.adjustsFontSizeToFitWidth = YES;
label.minimumFontSize = 10.0;
[label setFont:[UIFont boldSystemFontOfSize:16.0]];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[UIColor whiteColor]];
[label setText:@"My Favorite Title"];

[self.navigationItem setTitleView:label];
[label release];

Xcode: include ObjectiveC categories int static library

If you need to include ObjectiveC categories or other framework using ObjectiveC categories ( for example JSON framework ) into your own static library you probably get


-[__NSCFDictionary JSONRepresentation]: unrecognized selector sent to instance


In your project that using your static library you need to set in Project Settings for "Other Linker Flags" property two additional flags:

-ObjC
-all_load


Objective C: Merge two images

+ (UIImage*)mergeImage:(UIImage*)first withImage:(UIImage*)second
{
 // get size of the first image
 CGImageRef firstImageRef = first.CGImage;
 CGFloat firstWidth = CGImageGetWidth(firstImageRef);
 CGFloat firstHeight = CGImageGetHeight(firstImageRef);
 
 // get size of the second image
 CGImageRef secondImageRef = second.CGImage;
 CGFloat secondWidth = CGImageGetWidth(secondImageRef);
 CGFloat secondHeight = CGImageGetHeight(secondImageRef);
 
 // build merged size
 CGSize mergedSize = CGSizeMake(MAX(firstWidth, secondWidth), MAX(firstHeight, secondHeight));
 
 // capture image context ref
 UIGraphicsBeginImageContext(mergedSize);
 
 //Draw images onto the context
 [first drawInRect:CGRectMake(0, 0, firstWidth, firstHeight)];
 [second drawInRect:CGRectMake(0, 0, secondWidth, secondHeight)]; 
 
 // assign context to new UIImage
 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
 
 // end context
 UIGraphicsEndImageContext();

 return newImage;
}

If you want to resize new image to new desired size use function from previous post.

Objective C: Resize image

+ (UIImage*)resizeImageWithImage:(UIImage*)image toSize:(CGSize)newSize
{
    // Create a graphics image context
    UIGraphicsBeginImageContext(newSize);
 
    // draw in new context, with the new size
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
 
    // Get the new image from the context
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
 
    // End the context
    UIGraphicsEndImageContext();
 
    return newImage;
}

Android Emulator: invalid command-line parameter exception.

The default installation location is: C:\Program Files\Android\android-sdk.
If you set C:\Program Files\Android\android-sdk as SDK Location (Window -> Preferences -> Android) and try to run android application from Eclipse most likely you'll get an error:


[Emulator] invalid command-line parameter: Files\Android\android-sdk\tools/emulator-arm.exe.
[Emulator] Hint: use '@foo' to launch a virtual device named 'foo'.
[Emulator] please use -help for more information

In my opinion, this is because of space in Program Files,
so set SDK Location for 32-bit Windows

C:\PROGRA~1\Android\android-sdk

and for 64-bit Windows

C:\PROGRA~2\Android\android-sdk

WP7: Sending "POST" data and receive response

Let's send "POST" data from our Windows Phone and get response.
  1. Create Windows Phone Application named "SendPOSTdata".
  2. In MainPage.xaml.cs include some "using":
    using System;
    using System.IO;
    using System.Text;
    using System.Diagnostics;
    using System.Net;
    using System.Windows;
    using Microsoft.Phone.Controls;
    
  3. Create loaded event handler:
    using System;
    public MainPage()
    {
        InitializeComponent();
    
        Loaded += new RoutedEventHandler(MainPage_Loaded);
    }
    
    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        System.Uri myUri = new System.Uri("http://myPageUrlAddress.com/");
        HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(myUri);
        myRequest.Method = "POST";
        myRequest.ContentType = "application/x-www-form-urlencoded";
        myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback),myRequest);
    }
    
  4. Now we need create our "POST" data stream:
    void GetRequestStreamCallback(IAsyncResult callbackResult)
    {
        HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
        // End the stream request operation
        Stream postStream = myRequest.EndGetRequestStream(callbackResult);
    
        // Create the post data
        string postData = "param1=value1&param2=value2";
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
    
        // Add the post data to the web request
        postStream.Write(byteArray, 0, byteArray.Length);
        postStream.Close();
    
        // Start the web request
        myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
    }
    
  5. And at the end receive response:
    void GetResponsetStreamCallback(IAsyncResult callbackResult)
    {
        HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
        using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
        {
            string result = httpWebStreamReader.ReadToEnd();
            //For debug: show results
            Debug.WriteLine(result);
        }
    }
    
  6. Run.

WP7: How to Localize you DatePicker


  1. Create your DatePicker application described in this article or your own application.
  2. Insert in MainPage.xaml.cs
    using System.Globalization;
    using System.Threading;
    
  3. Windows Phone supports the display languages you may find here
  4. Next code fragment do all you need (of course you must choose "Culture code" you need):
    public MainPage()
    {
        CultureInfo newCulture = new CultureInfo("en-GB");
        Thread.CurrentThread.CurrentCulture = newCulture;
        Thread.CurrentThread.CurrentUICulture = newCulture;
    
        ...
    }
    
  5. But if your language not supported by windows phone?
    public MainPage()
    {
        CultureInfo newCulture = new CultureInfo("en-GB");
    
        //change format of DatePicker to you own format
        newCulture.DateTimeFormat.ShortDatePattern = "d/MMM/yyyy";
    
        //set day names
        newCulture.DateTimeFormat.DayNames = new string[] { "first day", 
                                                            "second day", 
                                                            "third day", 
                                                            "4 day", 
                                                            "5 day", 
                                                            "6 day", 
                                                            "7 day" };
    
        //set month names
        newCulture.DateTimeFormat.MonthNames = new string[] {"1 month", 
                                                             "2 month", 
                                                             "3 month", 
                                                             "4 month", 
                                                             "5 month", 
                                                             "6 month", 
                                                             "7 month", 
                                                             "8 month", 
                                                             "9 month", 
                                                             "10 month", 
                                                             "11 month", 
                                                             "12 month", 
                                                             ""};
    
        Thread.CurrentThread.CurrentCulture = newCulture;
        Thread.CurrentThread.CurrentUICulture = newCulture;
    
        ...
    }
    
  6. Enjoy

SourceForge.net: Mouse Wheeling Ticker: SCM

SourceForge.net: Mouse Wheeling Ticker: SCM

Mouse Wheeling Ticker - ticker to scroll any content (in any browser) without much action which does not load the CPU and allows the mouse wheel to scroll. Enjoy :)

WP7 - Create DatePicker control programmatically

If you need use DatePicker in your windows phone application you must create control field in xaml file. Or no...
Let's create DatePicker control programmatically without any code in xaml file.


  1. Install Silverlight Toolkit last version.
  2. Create new "Windows Phone Application" named "DatePickerControlProgrammatically".
  3. Adding new reference to Microsoft.Phone.Controls.Toolkit
    • Main Menu -> Project -> Add Reference -> Tab ".NET" -> choose Microsoft.Phone.Controls.Toolkit.
    • If you no find Microsoft.Phone.Controls.Toolkit in ".NET" tab go to "Browse" tab and navigate to this dll in you computer (for me "C:\Program Files\Microsoft SDKs\Windows Phone\v7.0\Toolkit\Sep10\Bin\Microsoft.Phone.Controls.Toolkit.dll").
  4. Create new folder in project "Toolkit.Content" and put inside two images for cancel and check control (you can get them in Silverlight Toolkit project or create you own icons):
  5. Don't forget change "Build Action" property for each image to "Content" from "Resource".
  6. Override DatePicker class with our custom DatePickerCustom class. Create new class "DatePickerCustom.cs":
    using System.Windows.Automation.Peers;
    using System.Windows.Automation.Provider;
    using System.Windows.Controls;
    using Microsoft.Phone.Controls;  
    
    namespace DatePickerControlProgrammatically
    {
        public class DatePickerCustom : DatePicker
        {
            public void ClickTemplateButton()
            {
                Button btn = (GetTemplateChild("DateTimeButton") as Button);
                ButtonAutomationPeer peer = new ButtonAutomationPeer(btn);
                IInvokeProvider provider = (peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider);
    
                provider.Invoke();
            }
        }
    }
    
  7. MainPage.xaml.cs - create new DatePickerCustom on Loaded event:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    namespace DatePickerControlProgrammatically
    {
        public partial class MainPage : PhoneApplicationPage
        {
            private DatePickerCustom datePicker;
    
            // Constructor
            public MainPage()
            {
                InitializeComponent();
    
                Loaded += new RoutedEventHandler(MainPage_Loaded);
            }
    
            void MainPage_Loaded(object sender, RoutedEventArgs e)
            {
                // create datePicker programmatically
                if (this.datePicker == null)
                {
                    this.datePicker = new DatePickerCustom();
                    this.datePicker.IsTabStop = false;
                    this.datePicker.MaxHeight = 0;
    
                    this.datePicker.ValueChanged += new EventHandler<DateTimeValueChangedEventArgs>(datePicker_ValueChanged);
    
                    LayoutRoot.Children.Add(this.datePicker);
    
                }
            }
    
            void datePicker_ValueChanged(object sender, DateTimeValueChangedEventArgs e)
            {
                // now we may use got value from datePicker
                PageTitle.Text = this.datePicker.ValueString;
            }
        }
    }
  8. For test add to MainPage.xaml two buttons - "Get Date" and "Clear Date":
    <Button Content="Get Date" Height="72" HorizontalAlignment="Left" 
        Name="button1" VerticalAlignment="Top" 
        Width="160" Click="button1_Click"/>
    <Button Content="Clear Date" Height="72" HorizontalAlignment="Right" 
        Name="button2" VerticalAlignment="Top" 
        Width="160" Click="button2_Click"/>
    

  9. And to MainPage.xaml.cs add control for our buttons:
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        this.datePicker.ClickTemplateButton();
    }
    
    private void button2_Click(object sender, RoutedEventArgs e)
    {
        PageTitle.Text = "Page Title";
        clearDatePicker();
    }
    
    void clearDatePicker()
    {
        this.datePicker.ValueChanged -= new EventHandler<DateTimeValueChangedEventArgs>(datePicker_ValueChanged);
    
        //this.datePicker.Value = "8/16/2011";
        this.datePicker.Value = null;
    
        this.datePicker.ValueChanged += new EventHandler<DateTimeValueChangedEventArgs>(datePicker_ValueChanged);
    }
    
  10. Run

WP7 - Download zip file, unzip and save to isolated storage


  1. Create New "Windows Phone Application".
  2. Download "Silverlight SharpZipLib" from http://slsharpziplib.codeplex.com/releases/view/50561.
  3. Unpack "Silverlight SharpZipLib" and copy Bin/Release/SharpZipLib.WindowsPhone7.dll
  4. Create new folder "SharpZip" and past into copied SharpZipLib.WindowsPhone7.dll.
  5. Right click on project and "Add Reference...".
  6. Choose from "Browse" tab SharpZipLib.WindowsPhone7.dll from your project location.
  7. Add to "MainPage.xaml.cs" (probably you need to remove "using System.Windows.Shapes" because conflict System.Windows.Shapes.Path vs System.IO.Path):
    using System.IO;
    using System.IO.IsolatedStorage;
    using ICSharpCode.SharpZipLib.Zip;
    using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
    
  8. Add code for download file from web:
    public MainPage()
    {
        InitializeComponent();
    
        Loaded += new RoutedEventHandler(MainPage_Loaded);
    }
    
    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        System.Uri targetUri = new System.Uri("http://MyDomain/Archive.zip");
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(targetUri);
        //create asynchronous tast and declare callback to get data stream
        request.BeginGetResponse(new AsyncCallback(ReadWebRequestCallback), request);
    }
    
  9. And add function "ReadWebRequestCallback" to unzip & save file we got:
    private void ReadWebRequestCallback(IAsyncResult callbackResult)
    {
        HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
        HttpWebResponse myResponse = (HttpWebResponse)myRequest.EndGetResponse(callbackResult);
        using (StreamReader httpwebStreamReader = new StreamReader(myResponse.GetResponseStream()))
        {
            //open isolated storage to save files
            using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (ZipInputStream s = new ZipInputStream(httpwebStreamReader.BaseStream))
                {
                    //s.Password = "123456";//if archive is encrypted
                    ZipEntry theEntry;
                    try
                    {
                        while ((theEntry = s.GetNextEntry()) != null)
                        {
                            string directoryName = Path.GetDirectoryName(theEntry.Name);
                            string fileName = Path.GetFileName(theEntry.Name);
    
                            // create directory
                            if (directoryName.Length > 0)
                            {
                                Directory.CreateDirectory(directoryName);
                            }
    
                            if (fileName != String.Empty)
                            {
                                //save file to isolated storage
                                using (BinaryWriter streamWriter = 
                                        new BinaryWriter(new IsolatedStorageFileStream(theEntry.Name,
                                            FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write, isoStore)))
                                {
    
                                    int size = 2048;
                                    byte[] data = new byte[2048];
                                    while (true)
                                    {
                                        size = s.Read(data, 0, data.Length);
                                        if (size > 0)
                                        {
                                            streamWriter.Write(data, 0, size);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
    
                            }
                        }
                    }
                    catch (ZipException ze)
                    {
                        Debug.WriteLine(ze.Message);
                    }
                }
            }
    
        }
    }
    

  10. Run your application and enjoy.

Zip/Unzip files on iPhone/iPad/iOS


  1. Download ZipArchive from http://code.google.com/p/ziparchive/downloads/list.
  2. Drag into project.
  3. Add to project existing framework libz.1.2.3.dylib (last version).
  4. Import to project:
    #import "ZipArchive.h"
    
  5. Uncompress zip file example:
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    
    NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:@"myZipFileName.zip"];
    
    NSString *output = [documentsDirectory stringByAppendingPathComponent:@"unZipDirName"];
    
    ZipArchive* za = [[ZipArchive alloc] init];
    
    if( [za UnzipOpenFile:zipFilePath] ) {
        if( [za UnzipFileTo:output overWrite:YES] != NO ) {
            //unzip data success
            //do something
        }
    
        [za UnzipCloseFile];
    }
    
    [za release];
    
  6. Compress directory or file example:
    BOOL isDir=NO;
    
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    
    NSArray *subpaths;
    
    NSString *toCompress = [NSString stringWithString:@"dirToZip_OR_fileNameToZip"];
    NSString *pathToCompress = [documentsDirectory stringByAppendingPathComponent:toCompress];
    
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    if ([fileManager fileExistsAtPath:pathToCompress isDirectory:&isDir] && isDir){
        subpaths = [fileManager subpathsAtPath:pathToCompress];
    } else if ([fileManager fileExistsAtPath:pathToCompress]) {
        subpaths = [NSArray arrayWithObject:pathToCompress];
    }
    
    NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:@"myZipFileName.zip"];
      
    ZipArchive *za = [[ZipArchive alloc] init];
    [za CreateZipFile2:zipFilePath];
    if (isDir) {
        for(NSString *path in subpaths){  
            NSString *fullPath = [pathToCompress stringByAppendingPathComponent:path];
            if([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir){
                [za addFileToZip:fullPath newname:path];  
            }
        }
    } else {
        [za addFileToZip:pathToCompress newname:toCompress];
    }
    
    BOOL successCompressing = [archiver CloseZipFile2];
    
    

WP7 - Load local HTML files and all related files (js, css) to WebBrowser

Agenda : we have several files html, css, js interconnected and we would start our web application in WebBrowser.
0. Create new project "SilverlightWebBrowser"
1. In the project navigator will create a new folder and name "HTML".
2. Copy all our files in that folder (if you want include image files don't forget change "Build Action" property of the images to "Content" from "Resource").


3. Add to MainPage.xaml code for show WebBrowser:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">
    <phone:WebBrowser IsScriptEnabled="True" Name="webBrowser1" Width="450" Height="548"/>
</Grid>

4. MainPage.xaml.cs

#define DEBUG

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Resources;
using Microsoft.Phone.Controls;

namespace SilverlightWebBrowser
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            SaveFilesInHTMLFolderToIsoStore();

            webBrowser1.Navigate(new Uri("HTML/Index.html", UriKind.Relative));

        }

        private static void SaveFilesInHTMLFolderToIsoStore()
        {
#if DEBUG
            // This deletes all existing files in IsolatedStorage - Useful in testing
            // In live should not do this, but only load files once - this speeds subsequent loading of the app
            using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                isoStore.Remove();
            }
#endif
            string[] files = AllFilesInHTMLFolder();

            using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                Debug.WriteLine("check for exist " + files[0]);
                if (!isoStore.FileExists(files[0]))
                {
                    foreach (string f in files)
                    {
                        Debug.WriteLine("copy to isolated storage " + f.ToString());
                        StreamResourceInfo sr = Application.GetResourceStream(new Uri(f, UriKind.Relative));

                        // T4 Template includes all files in source folder(s). This may include some which are not in the project
                        if (sr != null)
                        {
                            using (BinaryReader br = new BinaryReader(sr.Stream))
                            {
                                byte[] data = br.ReadBytes((int)sr.Stream.Length);
                                SaveFileToIsoStore(f, data);
                            }
                        }
                    }
                }
            }
        }

        private static void SaveFileToIsoStore(string fileName, byte[] data)
        {
            string strBaseDir = string.Empty;
            const string DelimStr = "/";
            char[] delimiter = DelimStr.ToCharArray();
            string[] dirsPath = fileName.Split(delimiter);

            // Get the IsoStore
            using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                // Recreate the directory structure
                for (int i = 0; i < dirsPath.Length - 1; i++)
                {
                    strBaseDir = Path.Combine(strBaseDir, dirsPath[i]);
                    isoStore.CreateDirectory(strBaseDir);
                }

                // Create the file if not exists
                // or override if exist
                using (BinaryWriter bw = new BinaryWriter(new IsolatedStorageFileStream(fileName,
                        FileMode.Create, FileAccess.Write, FileShare.Write, isoStore)))
                {
                    bw.Write(data);
                }
            }
        }



        //generated from MainPage.xaml.tt -> Run Custom Tool
        private static string[] AllFilesInHTMLFolder()
        {
            return new[] {
                           "HTML/index.css",
                           "HTML/Index.html",
                           "HTML/inner.js",
                        };
        }
    
    }
}

5. And then run emulator
6. Now We see our page with our css and js
7. But if we don't know in advance a list of files or it's large enough that would get lost, you can use preprocessed text template.

MainPage.xaml.tt

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".gen.cs" #>
<#@ import namespace="System.IO"#>
// <auto-generated />
using Microsoft.Phone.Controls;

namespace SilverlightWebBrowser
{
    public partial class MainPage : PhoneApplicationPage
    {
        private static string[] AllFilesInHTMLFolder()
        {
            return new[] {
<#
            DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(Host.TemplateFile), "HTML"));

            foreach(FileInfo file in directoryInfo.GetFiles("*.*", SearchOption.AllDirectories))
            {
    if (!file.FullName.Contains(@"\."))
    {#>
                           "<#= file.FullName.Substring(file.FullName.IndexOf("HTML")).Replace(@"\", "/") #>",
<#           }
   }
#>
                        };
        }
    }
}

8. Copy file MainPage.xaml.tt into project
    -> select file in navigation project
    -> right click -> Run Custom Tools
    -> open generated file MainPage.xaml.gen.cs
    -> we see our function AllFilesInHTMLFolder() with all exist files
    -> if you want to see all code in one place as copy/paste to MainPage.xaml.cs and delete MainPage.xaml.gen.cs. If no as go to 10.
10. It's all.

How to create additional localization on your iOS app - Files (plist, ...)

 1. Create a directory under project directory (in Finder) in format: language_region.lproj or language.lproj

languages list: ISO 639-2 Language Codes
regions list: ISO - Maintenance Agency

2. Right click on "Resource" in xCode project.
         Add ->
         New File ->
         Choose "Other" from Mac OS X ->
         Choose "Empty File" ->
         Next ->
         In "File Name" field change from "untitle" to "MyFileName.MyExtention" (usually Localizable.strings or MyFileName.plist) ->
         In "Location" field choose language_region.lproj folder you created ->
         Finish

3. Fill file with content do you want (copy/paste or replace file in Finder)

jQuery Equivalent of Prototype Function.bind with the transfer of arguments

MyClass = Class.create( {
...  
    displayFeeds: function(items){
        var ul = $('itemsList');
        for (var i = 0; i < items.length; i++) {
            var li = new Element('li');
            var text = new Element('a', {'href': '#'}).update(items[i].title);
            li.insert(text);
            ul.insert(li);
            text.observe('click', this.printDynamic.bind(this,items[i].link));
        }
    },

    localVar : "my class local variable",

    printDynamic: function(link){
        this.localVar = link;
    }
});

We have JQuery full equivalent below


MyClass = Class.create( {
...
    displayFeeds: function(items){
        var ul = $('#itemsList');
        for (var i = 0; i < items.length; i++) {
            var li = $("<li><a href='#DetailsScreen'>"+items[i].title+"</a></li>");
            li.bind('click',{url:items[i].link}, $.proxy(this.printDynamic, this));
            li.appendTo( ul );
        }
    },
    localVar : "my class local variable",
    printDynamic: function(event){
        this.localVar = event.data.url;
    }
});