29 Eylül 2012 Cumartesi

Php session da nesne saklamak

Session da değer saklayacağım zaman ben genellikle nesne olarak saklar ve erişirim.Bu şekilde kullanmakla hem oturum nesnesini optimize etmiş oluyoruz.Hemde kod yönetimini kolaylaştırıp,kalabalığı engellemiş oluyorum diye düşünüyorum.
İşte bir örnek :
 
 class User{
    public $rid;
    public $username;
    public $password;
 }

 $auser=new User();
 $auser->username='ismail';
 $auser->password='123';

 //nesnenin saklanması
 $_SESSION["user"]=serialize($auser);

 //session da saklanan "user" nesnesine erişim
 $auser = unserialize($_SESSION['user']);
 echo $auser->username;

İyi Çalışmalar..

25 Eylül 2012 Salı

Datasnap rest sunucusu ile iletişim(iOS Client)

Daha önce TDataset class'ına uzanım fonksiyonu olarak yazdığım ToJSONData isminde bir fonksiyonum vardı.Bu fonksiyon sayesinde veritabanında ki verileri kolayca json formatına çevirip dışarı sunabiliyordum.

Bu servislere de iOS ortamından erişmeyi görücez.

Person.h

@interface Person : NSObject
    @property(nonatomic) NSInteger rid;
    @property(nonatomic,retain) NSString *firstname;
    @property(nonatomic,retain) NSString *lastname;
@end

Person.m

#import "Person.h"

@implementation Person
  @synthesize rid;
  @synthesize firstname;
  @synthesize lastname;
@end

mainViewController.m

#import "mainViewController.h"
#import "Person.h"
#import "SBJson.h"

@interface mainViewController ()
  
@end

Person *person;
NSMutableArray * personlist;

@implementation mainViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
               
    personlist=[NSMutableArray new]; 
    NSURL *url = [[NSURL alloc] 
                  initWithString:@"http://192.168.1.7:8080/datasnap/rest/TServerMethods1/GetPersonList"];
    NSError *error = nil;
    NSStringEncoding encoding;
    NSString *rawjson = [[NSString alloc] initWithContentsOfURL:url
                                                   usedEncoding:&encoding 
                                                          error:&error];
    //formatting : [NSString stringWithFormat:@"%d", rawjson.length];
    if (rawjson.length!=0){
        SBJsonParser * parser=[SBJsonParser new];  
        NSDictionary *jsonObject = [parser objectWithString:rawjson error:&error];
    
        NSArray *mainlist = [jsonObject objectForKey:@"result"];
        NSArray *innerlist= [mainlist objectAtIndex:0];
        
        for (NSDictionary *item in innerlist) {
            person =[Person new];
            person.rid=[[item objectForKey:@"rid"] integerValue];
            person.firstname=[item objectForKey: @"firstname"]; 
            person.lastname=[item objectForKey: @"lastname"]; 
            [personlist addObject:person]; 
        }
    }
    // Uncomment the following line to preserve selection between presentations.
    // self.clearsneSelectionOnViewWillAppear = NO;
 
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}



- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    //warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
 //warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [personlist count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    // Configure the cell...
    Person * personItem=[personlist objectAtIndex:indexPath.row]; 
    cell.textLabel.text=[NSString stringWithFormat:@"%@ %@",
                         [personItem firstname],[personItem lastname]];
    return cell;
}




Demo :





Kaynaklar :

http://json.org/
http://stig.github.com/json-framework/
http://docwiki.embarcadero.com/RADStudio/en/DataSnap_REST_Messaging_Protocol
http://jasarien.com/?p=428
http://stackoverflow.com/questions/4919249/how-to-parse-json-into-objective-c-sbjson
http://stackoverflow.com/questions/3995519/how-to-use-stringwithcontentsofurlencodingerror
http://stackoverflow.com/questions/12567491/how-to-parse-this-json-data-with-objective-c-sbjsonparser

Hadi hayırlı işler. :)

Datasnap rest sunucusu ile iletişim(Delphi Client)

Forma bir tane TIdHttp nesnesi ekliyorsunuz.Daha sonra;
 //http://host:port/datasnap/rest/[ClassName]/[MethodName]/[ParamValue
 Memo1.Text:=IdHTTP1.Get('http://localhost:8080/datasnap/rest/TServerMethods1/GetPersonList');

Datasnap REST iletişim protokolü ve detaylar hakkında buradan malümat edinebilirsiniz

iPhone Simulator Simge Problemi

Hazırladığınız simgeleriniz iPhone simulator'de eğer gözükmüyorsa;

Çözüm :
X-Code IDE'sinden Product-> Clean ve Product->Build tıklayın.
Yeni simgeniz hayırlı olsun :)

10 Eylül 2012 Pazartesi

TDataset ToJSONData

{ İsmail Kocacan }
unit uJsonHelper;

interface

uses

  Data.DB,
  System.SysUtils,
  Data.DBXJSON,
  Data.DBXJSONCommon,
  Data.DBXJSONReflect;

type

  TDatasetJSONHelper = class helper for TDataset
  public
    function ToJSONData: TJSONArray;
  end;

implementation

{ TDatasetJSONHelper }
function TDatasetJSONHelper.ToJSONData: TJSONArray;
var
  jso: TJSONObject;
  jsa: TJSONArray;
  jsp: TJsonPair;
  J: Integer;
begin
  Self.Open;
  jsa := TJSONArray.Create();
  while not Self.Eof do
  begin
    jso := TJSONObject.Create();
    for J := 0 to FieldCount - 1 do
      jso.AddPair(TJsonPair.Create(Fields[J].DisplayName, Fields[J].Value));
    jsa.AddElement(jso);
    Self.Next;
  end;
  Self.Close;
  Result := jsa;
end;

end.
TDataset sınıfına uzanım fonksiyonu olarak yazmamızın sebebi; TDataset sınıfı kullanılarak genişletilen(kalıtılan) üst sınıflarda da,kolayca kullanabilelim diyedir.
 Örneğin ;
 SQLQuery1.ToJSONData;
 ADOQuery1.ToJSONData;
 UniQuery1.ToJSONData;
 BilmemNeQuery1.ToJSONData;

 Şeklinde kullanabilmek mümkün olacaktır.
 Örnek Çıktı
{
 "result":
  [
   {"RID":"3","FIRSTNAME":"serdar","LASTNAME":"sezer"},
   {"RID":"2","FIRSTNAME":"kemal","LASTNAME":"bayat"},
   {"RID":"1","FIRSTNAME":"ismail","LASTNAME":"kocacan"}
  ]
}
Yukarıdaki çıktıyı alabilmek için bir takım düzenlemeler yapmak gerekiyor.Bu düzenlemeleri Datasnap REST Ve JSON Formatı Hakkında konusunda bulabilirsiniz.

1 Eylül 2012 Cumartesi

Dependency Injection Giriş

{
  Inversion of Control
  Dependency injection at Delphi for Loose Coupling
  İsmail KOCACAN 2012
}

unit uMain;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs;

type
  IDocument = interface
    // GUID oluşturmak için kısayol : Ctrl+Shift+G
    ['{44E273D9-3C17-4821-B791-31CDDCE6C6D8}']
    procedure Parse;
  end;

  TBaseDocument = class abstract(TInterfacedObject)
  private
    FPath: string;
    FContent: string;
  public
    property Path: string read FPath write FPath;
    property Content: string read FContent write FContent;
  end;

  TXMLDocument = class(TBaseDocument, IDocument)
  public
    procedure Parse;
  end;

  TJSONDocument = class(TBaseDocument, IDocument)
  public
    procedure Parse;
  end;

  TDocumentParser = class
  private
    FDocument: IDocument;
  public
    constructor Create(aDocument: IDocument);
    procedure DoParse;
  end;

  TfrmMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

{ TXMLDocument }
procedure TXMLDocument.Parse;
begin
  OutputDebugString('XML parseleme işlemi yapıldı.');
end;

{ TJSONDocument }
procedure TJSONDocument.Parse;
begin
  OutputDebugString('JSON parseleme işlemi yapıldı.');
end;

{ TDocumentParser }
constructor TDocumentParser.Create(aDocument: IDocument);
begin
  FDocument := aDocument;
end;

procedure TDocumentParser.DoParse;
begin
  FDocument.Parse;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
var
  axmldocument: TXMLDocument;
  ajsondocument: TJSONDocument;
  aParser: TDocumentParser;
begin
  axmldocument := TXMLDocument.Create;
  aParser := TDocumentParser.Create(axmldocument);
  aParser.DoParse;

  ajsondocument := TJSONDocument.Create;
  aParser := TDocumentParser.Create(ajsondocument);
  aParser.DoParse;
end;

end.
TBaseDocument taban sınıfını, "IInterface" arayüzünün üyelerini implemente etmiş,
ve "TObject" sınıfın tüm özelliklerini bünyesinde barındıran "TInterfacedObject" sınıfından kalıtıyoruz.

"TBaseDocument" sınıfını "TInterfacedObject" sınıfından kalıtmamızın sebebi ise ;
Üst sınıflarda(TXMLDocument,TJSONDocument) "IDocument" arayüzünü implemente ederken
"IInterface" arayüzünün fonksiyonlarını da bizden implemente ettirmek istemesidir.
"TBaseDocument" sınıfından kalıtarak oluşturduğumuz her yeni sınıfın,"IInterface" arayüzünün methodlarını da, implemente ettirmek kullanışlı bir yöntem değil...

O Sebeble ; TBaseDocument taban sınıfımızı türetebileceğimiz,"IIInterface" arayüzünün fonksiyonlarını implemente etmiş,başka bir sınıf lazım.Bu ihtiyacı karşılayacak olan sınıfı kendimizde yazabilirdik fakat,
hali hazırda var olan "TInterfacedObject" ihtiyacımızı karşılıyor. "TBaseDocument" sınıfını TInterfacedObject sınıfından kalıtmamızın sebebi de budur.

"TXMLDocument" ve "TJSONDocument" sınıflarını "TBaseDocument" sınıfından türetiyoruz.
Ve "IDocument" arayüzünün methodlarını implemente ettiriyoruz.
Nitekim her yeni TBilmemneDocument nesnesinin Parse procedure'sinin gövdesinde farklı işlemler olacaktır.

Dependency injection prensibinin "Setter" procedure'ler ve Constructor methodlar ile uygulanadığını okumuştum.Tabiki bence sadece bunlarla sınırlı değil injection olayı...
Biz nesneleri dış dünyaya,o nesnenin üyeleri ile açtığımız için,bence sadece set edilebilen, bir property üzerinden de injection yapılabilir diye düşünüyorum...
injection kısmı ile daha kullanışlı yazım şekilleri aklımda var ama onlar bir daha ki sefere...

Dependency injection prensibin uygulandığı kısım ise "TDocumentParser" sınıfının yapılandırıcısında.
constructor Create(aDocument: IDocument);
Bu şekilde yazmakla derleyiciye şunu demiş oluyoruz.IDocument arayüzünde veya IDocument arayüzünü implemente etmiş bir sınıf, parametre olarak geçilebilir.Bu şekilde yazmak tipden bağımsız olduğu için, daha esnek bir kodlama oluyor.Nasıl yani? Esnek derken ?

Yani IDocument arayüzünü implemente etmiş,TBaseDocument sınıfında türeyen ,yeni yeni sınıflar yazıp,
TDocumentParser sınıfın yapılandırıcında hiçbir değişiklik yapmadan,bu yeni sınıfları parametre olarak geçebiliriz.Bu tipden bağımsız,soyutlama yöntemi ile yazım tarzıydı.


Şimdi birde soyutlamadan yazdığımızı düşünecek olursak;
constructor Create(aDocument: TXMLDocument); overload;
constructor Create(aDocument: TJSONDocument); overload;
Her yeni yazdığımız üst sınıfda(misal TBilmemneDocument) Parse methodunu çağırabilmemiz için,
constructor Create(aDocument: TBilmemneDocument); overload; gibi değişikliği veya başka bir yazım tarzını, "TDocumentParser" sınıfında yapmamız gerekecekti.


Rtti ve Dependency Injection ile ilgili aklımda bir senaryo da var.
Bir daha ki sefere...


Kaynak kodları(XE2) buradan indirebilirsiniz

Kaynaklar : 
http://martinfowler.com/articles/injection.html
http://www.kodcu.com/2011/04/inversion-of-control-ioc-nedir/