IOS(sandbox)沙盒和檔案操作(NSFileManager)
目錄:
IOS學習之IOS沙盒(sandbox)機制和檔案操作(一)
1、IOS沙盒機制
IOS應用程式只能在為該改程式建立的檔案系統中讀取檔案,不可以去其它地方訪問,此區域被成為沙盒,所以所有的非程式碼檔案都要儲存在此,例如影象,圖示,聲音,映像,屬性列表,文字檔案等。
1.1、每個應用程式都有自己的儲存空間
1.2、應用程式不能翻過自己的圍牆去訪問別的儲存空間的內容
1.3、應用程式請求的資料都要通過許可權檢測,假如不符合條件的話,不會被放行。
通過這張圖只能從表層上理解sandbox是一種安全體系,應用程式的所有操作都要通過這個體系來執行,其中核心內容是:sandbox對應用程式執行各種操作的許可權限制。
2、開啟模擬器沙盒目錄
下面看看模擬器的沙盒資料夾在mac電腦上的什麼位置。
檔案都在個人使用者名資料夾下的一個隱藏資料夾裡,中文叫資源庫,他的目錄其實是Library。
2.1 方法1、可以設定顯示隱藏檔案,然後在Finder下直接開啟。設定檢視隱藏檔案的方法如下:開啟終端,輸入命名
顯示Mac隱藏檔案的命令:defaults write com.apple.finder AppleShowAllFiles -bool true
隱藏Mac隱藏檔案的命令:defaults write com.apple.finder AppleShowAllFiles -bool false
輸完單擊Enter鍵,退出終端,
重新啟動Finder就可以了重啟Finder:滑鼠單擊視窗左上角的蘋果標誌-->強制退出-->Finder-->
現在能看到資源庫檔案夾了。
開啟資源庫後找到/Application Support/iPhone Simulator/資料夾。這裡面就是模擬器的各個程式的沙盒目錄了。
2.2 方法2、這種方法更方便,在Finder上點->前往->前往資料夾,輸入/Users/username/Library/Application Support/iPhone Simulator/ 前往。
username這裡寫你的使用者名稱。
3、目錄結構
預設情況下,每個沙盒含有3個資料夾:Documents, Library 和 tmp。因為應用的沙盒機制,應用只能在幾個目錄下讀寫檔案
Documents:蘋果建議將程式中建立的或在程式中瀏覽到的檔案資料儲存在該目錄下,iTunes備份和恢復的時候會包括此目錄
Library:儲存程式的預設設定或其它狀態資訊;
Library/Caches:存放快取檔案,iTunes不會備份此目錄,此目錄下檔案不會在應用退出刪除
tmp:提供一個即時建立臨時檔案的地方。
iTunes在與iPhone同步時,備份所有的Documents和Library檔案。
iPhone在重啟時,會丟棄所有的tmp檔案。
我們建立一個IosSandbox的專案來展開沙盒和檔案讀寫等操作的練習。
建立後找到模擬器上對應的目錄,
這是目錄全展開了。
這是上面提到的三個目錄 :Documents、Library、 tmp
下篇介紹目錄路徑獲取和檔案操作
IOS學習之IOS沙盒(sandbox)機制和檔案操作(二)
我們看看如何獲取應用程式沙盒目錄。包括真機的沙盒的目錄。
1、獲取程式的Home目錄
NSString *homeDirectory = NSHomeDirectory(); NSLog(@"path:%@", homeDirectory); |
列印結果:
2012-06-17 14:00:06.098 IosSandbox[3536:f803] /Users/rongfzh/Library/Application Support/iPhone Simulator/5.1/ Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2 |
那在真機上的目錄有是怎麼樣的呢?我們看看
2012-06-17 14:25:47.059 IosSandbox[4281:f803] /var/mobile/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2
可見,真機上的目錄是/var/mobile/Applications/這個目錄下的,和模擬器不一樣。這個是Home目錄,其他的子目錄和模擬器一樣。
2、獲取document目錄
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *path = [paths objectAtIndex:0]; NSLog(@"path:%@", path); |
列印結果
2012-06-17 14:00:06.099 IosSandbox[3536:f803] path:/Users/rongfzh/Library/Application Support/iPhone Simulator/5.1 /Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Documents |
3、獲取Cache目錄
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *path = [paths objectAtIndex:0]; NSLog(@"%@", path); |
列印結果:
2012-06-17 14:03:50.431 IosSandbox[3628:f803] /Users/rongfzh/Library/Application Support/iPhone Simulator/5.1 /Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Library/Caches |
4、獲取Library目錄
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *path = [paths objectAtIndex:0]; NSLog(@"%@", path); |
列印結果:
2012-06-17 14:07:17.544 IosSandbox[3733:f803] /Users/rongfzh/Library/Application Support/iPhone Simulator/5.1 /Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Library |
5、獲取Tmp目錄
NSString *tmpDir = NSTemporaryDirectory(); NSLog(@"%@", tmpDir); |
列印結果:
2012-06-17 14:08:07.824 IosSandbox[3782:f803] /var/folders/g7/246bh79130zblw0yjjtc55cw0000gn/T/ |
6、寫入檔案
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docDir = [paths objectAtIndex:0]; if (!docDir) { NSLog(@"Documents 目錄未找到"); } NSArray *array = [[NSArray alloc] initWithObjects:@"內容",@"content",nil]; NSString *filePath = [docDir stringByAppendingPathComponent:@"testFile.txt"]; [array writeToFile:filePath atomically:YES]; |
注:我們在真機上也執行一下,把檔案寫入,下一步從真機上把內容讀取出來。
寫入輸入 array ,裡面是兩個字串,一會我們讀出來列印。
寫入我們在程式沙盒目錄下看到檔案 testFile.txt
開啟檔案看到的內容是這樣的,是個xml格式的plist檔案,資料格式儲存了內容。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <array> <string>內容</string> <string>content</string> </array> </plist> |
7、讀取檔案
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docDir = [paths objectAtIndex:0]; NSString *filePath = [docDir stringByAppendingPathComponent:@"testFile.txt"]; NSArray *array = [[NSArray alloc]initWithContentsOfFile:filePath]; NSLog(@"%@", array); |
列印結果:
把上面的檔案解析後,把內容打印出來了。
2012-06-17 14:14:46.249 IosSandbox[3918:f803] ( "\U5185\U5bb9", content ) |
真機上讀取並列印檔案路徑:
2012-06-17 14:25:47.059 IosSandbox[4281:f803] /var/mobile/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Documents/testFile.txt
(
"\U5185\U5bb9",
content
)
真機上也能寫入和列印。
IOS學習之IOS沙盒(sandbox)機制和檔案操作之NSFileManager(三)
我們看看NSFileManager如何使用。包括建立檔案,目錄,刪除,遍歷目錄等。
1、在Documents裡建立目錄
建立一個叫test的目錄,先找到Documents的目錄,
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSLog(@"documentsDirectory%@",documentsDirectory); NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *testDirectory = [documentsDirectory stringByAppendingPathComponent:@"test"]; // 建立目錄 [fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil]; |
啟動程式,這時候目錄就建立了:
2、在test目錄下建立檔案
建立檔案怎麼辦呢?接著上面的程式碼 testPath 要用stringByAppendingPathComponent拼接上你要生成的檔名,比如test00.txt。這樣才能在test下寫入檔案。
testDirectory是上面程式碼生成的路徑哦,不要忘了。我往test資料夾裡寫入三個檔案,test00.txt ,test22.txt,text.33.txt。內容都是寫入內容,write String。
實現程式碼如下:
NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test00.txt"]; NSString *testPath2 = [testDirectory stringByAppendingPathComponent:@"test22.txt"]; NSString *testPath3 = [testDirectory stringByAppendingPathComponent:@"test33.txt"]; NSString *string = @"寫入內容,write String"; [fileManager createFileAtPath:testPath contents:[string dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; [fileManager createFileAtPath:testPath2 contents:[string dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; [fileManager createFileAtPath:testPath3 contents:[string dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; |
看下面的圖,三個檔案都出來了,內容也對。
在Documents目錄下建立就更簡單了,不用加test就ok了
3、獲取目錄列裡所有檔名
兩種方法獲取:subpathsOfDirectoryAtPath 和 subpathsAtPath
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSLog(@"documentsDirectory%@",documentsDirectory); NSFileManager *fileManage = [NSFileManager defaultManager]; NSString *myDirectory = [documentsDirectory stringByAppendingPathComponent:@"test"]; NSArray *file = [fileManage subpathsOfDirectoryAtPath: myDirectory error:nil]; NSLog(@"%@",file); NSArray *files = [fileManage subpathsAtPath: myDirectory ]; NSLog(@"%@",files); |
獲取上面剛才test資料夾裡的檔名
列印結果
2012-06-17 23:23:19.684 IosSandbox[947:f803] fileList:( ".DS_Store", "test00.txt", "test22.txt", "test33.txt" ) 2012-06-17 23:23:19.686 IosSandbox[947:f803] fileLit( ".DS_Store", "test00.txt", "test22.txt", "test33.txt" ) |
兩個方法都可以,隱藏的檔案也打印出來了。
4、fileManager使用操作當前目錄
//建立檔案管理器 NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; //更改到待操作的目錄下 [fileManager changeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]]; //建立檔案fileName檔名稱,contents檔案的內容,如果開始沒有內容可以設定為nil,attributes檔案的屬性,初始為nil NSString * fileName = @"testFileNSFileManager.txt"; NSArray *array = [[NSArray alloc] initWithObjects:@"hello world",@"hello world1", @"hello world2",nil]; [fileManager createFileAtPath:fileName contents:array attributes:nil]; |
這樣就建立了testFileNSFileManager.txt並把三個hello world寫入檔案了
changeCurrentDirectoryPath目錄更改到當前操作目錄時,做檔案讀寫就很方便了,不用加上全路徑
5、刪除檔案
接上面的程式碼,remove就ok了。
[fileManager removeItemAtPath:fileName error:nil]; |
6、混合資料的讀寫
用NSMutableData建立混合資料,然後寫到檔案裡。並按資料的型別把資料讀出來
6.1寫入資料:
NSString * fileName = @"testFileNSFileManager.txt"; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; //獲取檔案路徑 NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName]; //待寫入的資料 NSString *temp = @"nihao 世界"; int dataInt = 1234; float dataFloat = 3.14f; //建立資料緩衝 NSMutableData *writer = [[NSMutableData alloc] init]; //將字串新增到緩衝中 [writer appendData:[temp dataUsingEncoding:NSUTF8StringEncoding]]; //將其他資料新增到緩衝中 [writer appendBytes:&dataInt length:sizeof(dataInt)]; [writer appendBytes:&dataFloat length:sizeof(dataFloat)]; //將緩衝的資料寫入到檔案中 [writer writeToFile:path atomically:YES]; |
我們看看資料怎麼樣了:
我們看到後面的是亂碼,那是中文被轉成了NSData後,還有int float的二進位制
6.2讀取剛才寫入的資料:
//讀取資料: int intData; float floatData = 0.0; NSString *stringData; NSData *reader = [NSData dataWithContentsOfFile:path]; stringData = [[NSString alloc] initWithData:[reader subdataWithRange:NSMakeRange(0, [temp length])] encoding:NSUTF8StringEncoding]; [reader getBytes:&intData range:NSMakeRange([temp length], sizeof(intData))]; [reader getBytes:&floatData range:NSMakeRange([temp length] + sizeof(intData), sizeof(floatData))]; NSLog(@"stringData:%@ intData:%d floatData:%f", stringData, intData, floatData); |
打印出來的結果:
2012-06-17 23:51:14.723 IosSandbox[1285:f803] stringData:nihao hello! intData:1234332 floatData:3.140000
這裡把寫入的漢字改成了 hello。因為[temp length]算長度是,把中文算成一位了,出來的結果有誤。
NSFileHandle(檔案控制代碼)
//檔案控制代碼,可以當做就是檔案本身,對控制代碼進行操作,相當於是對檔案本身進行操作
//讀---將資料從磁碟轉移到記憶體
//寫---將資料從記憶體轉移到磁碟
1.+ (id)fileHandleForReadingAtPath:(NSString *)path;
讀取制定路徑下的內容,返回值為一個控制代碼
//建立讀取檔案的控制代碼
//注意:如果失敗那麼控制代碼為空
NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:PATH];
//NSLog(@"%p",readHandle);
//讀取指定長度的檔案內容
//- (NSData *)readDataOfLength:(NSUInteger)length;
2. NSData *data = [readHandle readDataOfLength:3];
把控制代碼設為3,返回值為一個二進位制的資料流
NSLog(@"%@",data);
3. 把二進位制的資料流轉換成字串輸出
NSString *fileContents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",fileContents);
4.讀取檔案直到最後
data = [readHandle readDataToEndOfFile];
把控制代碼設成末尾返回的時整個檔案內容的資料流
fileContents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",fileContents);
//字串直接讀取檔案,只能把檔案完整讀取
5. NSString *str = [NSString stringWithContentsOfFile:PATH encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",str);
讀取檔案的內容在制定的路徑下
6.設定檔案控制代碼為某一個值
[readHandle seekToFileOffset:3];
把控制代碼設成3.
data = [readHandle readDataToEndOfFile];
fileContents = [[NSString alloc]
initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",fileContents);
讀取三個位元組的內容
7.NSFileHandle *writeHandle = [NSFileHandle fileHandleForWritingAtPath:PATH];
建立一個用於寫檔案的控制代碼
8.NSData *data = [@"ZZZ" dataUsingEncoding:NSUTF8StringEncoding];
把字串轉換成二進位制的資料流,
//往檔案裡面寫東西,會一個位元組一個位元組覆蓋
//[writeHandle writeData:data];
//前面使用的控制代碼會將值保留下來,下一次接著用
//[writeHandle writeData:data];
NSLog(@"-----");
//- (unsigned long long)seekToEndOfFile;
//直接把控制代碼定位到檔案的最末尾
//unsigned long long index = [writeHandle seekToEndOfFile];
//NSLog(@"%lld",index);
[writeHandle writeData:data];
//截斷檔案到指定大小
[writeHandle truncateFileAtOffset:3];
//NSString *str = @"ZZZ";
//字串直接寫入檔案,會把以前的內容覆蓋掉
//[str writeToFile:PATH atomically:YES encoding:NSUTF8StringEncoding error:nil];
//把內容同步到磁碟
9.寫完要儲存.[writeHandle synchronizeFile];
檔案拷貝舉例
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSFileManager *manager = [NSFileManager defaultManager];
NSString *path1 = @"/users/qianfeng/desktop/海闊天空.txt";
NSString *path2 = @"/users/qianfeng/desktop/img/海闊天空.txt";
BOOL isdir = NO;
BOOL rec = [manager fileExistsAtPath:path2 isDirectory:&isdir];
if(!rec)
{
[manager createFileAtPath:path2 contents:nil attributes:nil];
NSFileHandle *read = [NSFileHandle fileHandleForReadingAtPath:path1];
NSFileHandle *write = [NSFileHandle fileHandleForWritingAtPath:path2];
NSDictionary *dic = [manager attributesOfItemAtPath:path1 error:nil];
NSNumber *length = [dic objectForKey:@"NSFileSize"];
NSLog(@"%@",length);
int l = [length intValue];
while(l >0)
{
if(l < 100)
{
NSData *data = [read readDataToEndOfFile];
[write writeData:data];
l = 0;
}
else
{
NSData *data = [read readDataOfLength:100];
[write writeData:data];
l-=100;
}
}
[write synchronizeFile];
}
else
{
if(isdir)
{
NSLog(@"這是一個目錄");
}
else
{
NSLog(@"檔案已經存在");
}
return 0;
}
}
return 0;
}
PDF歸類
int main()
{
@autoreleasepool {
NSError *__autoreleasing *err=nil;
NSFileManager *manager=[NSFileManager defaultManager];
NSArray *contens=[manager subpathsOfDirectoryAtPath:PATH error:&err];
NSLog(@"%@",err);
for (id obj in contens)
{
if ([obj rangeOfString:@"."].location) {
NSLog(@"%@",obj);
NSArray *arr=[obj componentsSeparatedByString:@"."];
NSArray *arr1=[obj componentsSeparatedByString:@"/"];
NSString *str=[arr objectAtIndex:[arr count]-1];
NSString *str1=[arr1 objectAtIndex:[arr1 count]-1];
[manager createDirectoryAtPath:[NSString stringWithFormat:@"%@/%@",PATH,str] withIntermediateDirectories:NO attributes:nil error:nil];
[manager copyItemAtPath:[NSString stringWithFormat:@"%@/%@",PATH,str1] toPath:[NSString stringWithFormat:@"%@/%@",PATH,str] error:nil];
}
}
}
}
所有圖片都移動到新的資料夾
int main()
{
@autoreleasepool {
NSError *__autoreleasing *err=nil;
NSFileManager *manager=[NSFileManager defaultManager];
NSArray *contens=[manager subpathsOfDirectoryAtPath:PATH error:&err];
NSLog(@"%@",err);
for (id obj in contens)
{
if ([obj rangeOfString:@"."].location) {
NSLog(@"%@",obj);
NSArray *arr=[obj componentsSeparatedByString:@"."];
NSArray *arr1=[obj componentsSeparatedByString:@"/"];
NSString *str=[arr objectAtIndex:[arr count]-1];
NSString *str1=[arr1 objectAtIndex:[arr1 count]-1];
[manager createDirectoryAtPath:[NSString stringWithFormat:@"%@/%@",PATH,str] withIntermediateDirectories:NO attributes:nil error:nil];
[manager copyItemAtPath:[NSString stringWithFormat:@"%@/%@",PATH,str1] toPath:[NSString stringWithFormat:@"%@/%@",PATH,str] error:nil];
}
}
}
}
檔案內容讀取和json解析
#import <Foundation/Foundation.h>
//檔案內容的操作
//NSFileHandle
#define PATH @"/users/chancelee/desktop/test.txt"
#if 0
int main(int argc, const char * argv[])
{
@autoreleasepool {
//檔案控制代碼,可以當做就是檔案本身,對控制代碼進行操作,相當於是對檔案本身進行操作
//讀---將資料從磁碟轉移到記憶體
//寫---將資料從記憶體轉移到磁碟
//+ (id)fileHandleWithNullDevice;
//+ (id)fileHandleForReadingAtPath:(NSString *)path;
//建立讀取檔案的控制代碼
//注意:如果失敗那麼控制代碼為空
NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:PATH];
//NSLog(@"%p",readHandle);
//讀取指定長度的檔案內容
//- (NSData *)readDataOfLength:(NSUInteger)length;
NSData *data = [readHandle readDataOfLength:3];
NSLog(@"%@",data);
NSString *fileContents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",fileContents);
//讀取檔案直到最後
data = [readHandle readDataToEndOfFile];
fileContents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",fileContents);
//字串直接讀取檔案,只能把檔案完整讀取
NSString *str = [NSString stringWithContentsOfFile:PATH encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",str);
//設定檔案控制代碼為某一個值
[readHandle seekToFileOffset:3];
data = [readHandle readDataToEndOfFile];
fileContents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",fileContents);
}
return 0;
}
#endif
int main()
{
NSFileHandle *writeHandle = [NSFileHandle fileHandleForWritingAtPath:PATH];
NSData *data = [@"ZZZ" dataUsingEncoding:NSUTF8StringEncoding];
//往檔案裡面寫東西,會一個位元組一個位元組覆蓋
//[writeHandle writeData:data];
//前面使用的控制代碼會將值保留下來,下一次接著用
//[writeHandle writeData:data];
NSLog(@"-----");
//- (unsigned long long)seekToEndOfFile;
//直接把控制代碼定位到檔案的最末尾
//unsigned long long index = [writeHandle seekToEndOfFile];
//NSLog(@"%lld",index);
[writeHandle writeData:data];
//截斷檔案到指定大小
[writeHandle truncateFileAtOffset:3];
//NSString *str = @"ZZZ";
//字串直接寫入檔案,會把以前的內容覆蓋掉
//[str writeToFile:PATH atomically:YES encoding:NSUTF8StringEncoding error:nil];
//把內容同步到磁碟
[writeHandle synchronizeFile];
}
//json
//json的資料格式:
//[]陣列
//{}字典
//"":""鍵值對
//多個鍵值對之間以,隔開
//不同於xml,輕量級,減少冗餘的資料,縮短下載的時間,節省流量
#define PATH @"/users/chancelee/desktop/test.json"
int main(int argc, const char * argv[])
{
@autoreleasepool {
//可以直接用字串將json檔案讀取出來
NSString *str = [NSString stringWithContentsOfFile:PATH encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",str);
//NSJSONSerialization
NSData *data = [NSData dataWithContentsOfFile:PATH];
NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
/**
* typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) {
NSJSONReadingMutableContainers = (1UL << 0), 指定成可變的陣列或者字典
NSJSONReadingMutableLeaves = (1UL << 1), 指定成可變字串
NSJSONReadingAllowFragments = (1UL << 2) 不指定解析的型別
};
*/
id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"%@",obj);
NSLog(@"%@",[obj class]);
}
return 0;
}