{"id":18512679,"url":"https://github.com/knightsj/sjnetwork","last_synced_at":"2025-08-20T04:32:39.498Z","repository":{"id":62453814,"uuid":"115445190","full_name":"knightsj/SJNetwork","owner":"knightsj","description":"SJNetwork is a high level network request tool based on AFNetworking and inspired on YTKNetwork.","archived":false,"fork":false,"pushed_at":"2020-01-03T20:25:49.000Z","size":1662,"stargazers_count":236,"open_issues_count":6,"forks_count":36,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-12-06T19:53:47.351Z","etag":null,"topics":["afnetworking","cache","download","image","network","upload","ytknetwork"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knightsj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-26T18:20:15.000Z","updated_at":"2024-06-07T01:40:27.000Z","dependencies_parsed_at":"2022-11-02T00:01:20.990Z","dependency_job_id":null,"html_url":"https://github.com/knightsj/SJNetwork","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightsj%2FSJNetwork","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightsj%2FSJNetwork/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightsj%2FSJNetwork/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knightsj%2FSJNetwork/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knightsj","download_url":"https://codeload.github.com/knightsj/SJNetwork/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230394228,"owners_count":18218707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["afnetworking","cache","download","image","network","upload","ytknetwork"],"created_at":"2024-11-06T15:34:58.595Z","updated_at":"2024-12-19T07:06:46.105Z","avatar_url":"https://github.com/knightsj.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SJNetwork\n\n![](https://img.shields.io/badge/build-passing-brightgreen.svg)\n![](https://img.shields.io/badge/platform-iOS-lightgrey.svg)\n![](https://img.shields.io/badge/language-Objective--C-30A3FC.svg)\n![](https://img.shields.io/badge/pod-v1.2.0-orange.svg)\n[![](https://img.shields.io/badge/blog-JueJin-007FFF.svg)](https://juejin.im/post/5a3f4ae8f265da4322416967)\n[![](https://img.shields.io/badge/weibo-%40J__Knight__-ff0000.svg)](https://weibo.com/1929625262/profile?rightmod=1\u0026wvr=6\u0026mod=personinfo\u0026is_all=1)\n[![](https://img.shields.io/badge/License-MIT-ff69b4.svg)](https://github.com/knightsj/SJNetwork/blob/master/LICENSE)\n\n## Introduction\n\n\n\nSJNetwork provides a high level network request API  based on AFNetworking and inspired by YTKNetwork: generating network request object according to the configuration of a specific network request(url, method, parameters etc.)  and managing requests by the corresponding objects.\n\nDocument for Chinese-convenient reader:[中文文档](https://juejin.im/post/5a3f4ae8f265da4322416967)\n\n\n## Features\n\n\n\n- **Ordinary request**: sending GET,POST,PUT,DELETE network request.\n  - write and load caches, configure cache available time duration​\n- **Upload request**: sending upload image(s) network request\n  - one and more than one image uploading and configure compress ratio before uploading​\n- **Download request**: sending download file network request\n  - resumable or not\n  - background downloading supporting or not\n- **Default parameters**:default parameters will be added on request body\n- **Custom header**: configuring custom request header(key-value)\n- **Base url configuration**  : server url of network requests\n- **Request management**:canceling one or more than one current network requests; checking current requests' information\n- **Cache operation**: writing, loading or clearing one or more than one cache of network requests ; calculating cache size\n- **Debug mode switch**: for convenience of debugging\n\n\n\n\n\n\n## Usage\n\n\n**Method1:**  using Cocoapods:\n\n``pod 'SJNetwork'``\n\nthen\n\n```objective-c\n#import \u003cSJNetwork/SJNetwork.h\u003e\n```\n\n\n\n**Method2**: moving ``SJNetwork``folder into your project.\n\nthen\n\n```objective-c\n#import \"SJNetwork.h\"\n```\n\n\n\n### Basic Configuration\n\n\n\n#### Server url\n\n```objective-c\n[SJNetworkConfig sharedConfig].baseUrl = @\"http://v.juhe.cn\";\n```\n\n\n\n#### Default parameters\n\n```objective-c\n[SJNetworkConfig sharedConfig].defailtParameters = @{@\"app_version\":[[[NSBundle mainBundle] infoDictionary] objectForKey:@\"CFBundleShortVersionString\"],\n                                                        @\"platform\":@\"iOS\"};\n```\n\n\n\n#### Timeout seconds\n\n```objective-c\n[SJNetworkConfig sharedConfig].timeoutSeconds = 30;//default is 20s\n```\n\n\n\n#### Debug mode\n\n```objective-c\n[SJNetworkConfig sharedConfig].debugMode = YES;//default is NO\n```\n\n\n\n\n\n#### Add request header\n\n```objective-c\n[[SJNetworkConfig sharedConfig] addCustomHeader:@{@\"token\":@\"2j4jd9s74bfm9sn3\"}];\n```\n\nor\n\n```objective-c\n[[SJNetworkManager sharedManager] addCustomHeader:@{@\"token\":@\"2j4jd9s74bfm9sn3\"}];\n```\n\n\n\n\u003e The input key-value pair will be added in network request header.\n\u003e\n\u003e If a pair with same key-value dose not exist, then add it, if it exists, then replace it.\n\n\n\n\n\n### Ordinary Network Request\n\n\nPOST request (none writing or none loading cache):\n\n```objective-c\n[[SJNetworkManager sharedManager] sendPostRequest:@\"toutiao/index\"\n                                       parameters:@{@\"type\":@\"top\",\n                                                    @\"key\" :@\"0c60\"}\n  \n     success:^(id responseObject) {\n\n  } failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode) {\n\n  }];\n```\n\n\n\nPOST request ( writing and loading cache):\n\n\n\n```objective-c\n[[SJNetworkManager sharedManager] sendPostRequest:@\"toutiao/index\"\n                                       parameters:@{@\"type\":@\"top\",\n                                                    @\"key\" :@\"0c60\"}\n                                        loadCache:YES\n                                    cacheDuration:180\n  success:^(id responseObject) {\n\n} failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode) {\n\n}];\n```\n\n\n\n\u003e If loadcache is set to be YES, then try to load cache before sending network request.\n\u003e\n\u003e If cacheDuration is set to be more than 0, then write cache after receiving response object.\n\n\n\nFlow chart of cache operation in ordinary requests:\n\n![](http://oih3a9o4n.bkt.clouddn.com/request-blackwhite.png)\n\n\n\n### Cache Operation\n\n \n\n#### Loading cache\n\n\n\nLoading cache of a specific network request:\n\n```objective-c\n[[SJNetworkManager sharedManager] loadCacheWithUrl:@\"toutiao/index\"\n                                            method:@\"POST\"\n                                        parameters:@{@\"type\":@\"top\",\n                                                     @\"key\" :@\"0c60\"}\n                                 completionBlock:^(id  _Nullable cacheObject) {                               \n}];\n```\n\n\n\nLoading cache of network requests share the same request url:\n\n```objective-c\n[[SJNetworkManager sharedManager] loadCacheWithUrl:@\"toutiao/index\"\n                                   completionBlock:^(NSArray * _Nullable cacheArr) {\n}];\n```\n\n\n\nLoading cache of network requests which share the same request url and method:\n\n```objective-c\n[[SJNetworkManager sharedManager] loadCacheWithUrl:@\"toutiao/index\"\n                                            method:@\"POST\"\n                                   completionBlock:^(NSArray * _Nullable cacheArr) {\n}];\n```\n\n\n\n#### Clearing Cache\n\n\n\nClearing cache of one specific network request:\n\n```objective-c\n[[SJNetworkManager sharedManager] clearCacheWithUrl:@\"toutiao/index\"\n                                             method:@\"POST\"\n                                         parameters:@{@\"type\":@\"top\",\n                                                      @\"key\" :@\"0c60\"}\n                                    completionBlock:^(BOOL isSuccess) {\n}];\n```\n\n\n\n\n\nClearing cache of network requests share the same request url:\n\n```objective-c\n[[SJNetworkManager sharedManager] clearCacheWithUrl:@\"toutiao/index\"\n                                    completionBlock:^(BOOL isSuccess) {\n}];\n```\n\n\n\n\n\nClearing cache of network requests which share the same request url and method:\n\n```objective-c\n[[SJNetworkManager sharedManager] clearCacheWithUrl:@\"toutiao/index\"\n                                             method:@\"POST\"\n                                    completionBlock:^(BOOL isSuccess) {\n}];\n```\n\n\n\n#### Calculating Cache\n\nCalculating the size of cache folder:\n\n```objective-c\n[[SJNetworkManager sharedManager] calculateCacheSizeWithCompletionBlock:^(NSUInteger fileCount, NSUInteger totalSize, NSString *totalSizeString) {\n        \n        NSLog(@\"file count :%lu and total size:%lu total size string:%@\",(unsigned long)fileCount,(unsigned long)totalSize, totalSizeString);\n        \n}];\n```\n\n\n\n\u003e **fileCount**:file counts in cache folder\n\u003e\n\u003e **totalSize**: size of cache folder(unit is byte)\n\u003e\n\u003e **totalSizeString**:size of cache folder (size of unit)  eg.``file count :5 and total size:1298609 total size string:1.2385 MB``\n\n\n\n\n\n\n\n### Uploading Function\n\nUploading one image, original size:\n\n\n\n```objective-c\n[[SJNetworkManager sharedManager]  sendUploadImageRequest:@\"api\"\n                                               parameters:nil\n                                                    image:image_1\n                                                     name:@\"universe\"\n                                                 mimeType:@\"png\"\n                                                 progress:^(NSProgress *uploadProgress) {\n                                                        \n  self.progressView.observedProgress = uploadProgress;\n\n} success:^(id responseObject) {\n\n} failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode, NSArray\u003cUIImage *\u003e *uploadFailedImages) {\n\n}];\n```\n\n\n\n\u003e Here, the mimeType can be jpg/JPG, png/PNG, jpeg/JPEG and if the user gives a wrong type, the mimeType will be jpg.\n\n\n\nUploading two images, compress ratio is 0.5(note that if the mineType is 'png' or 'PNG', the compressRatio will be useless):\n\n\n\n```objective-c\n[[SJNetworkManager sharedManager]  sendUploadImagesRequest:@\"api\"\n                                                parameters:nil\n                                                    images:@[image_1,image_2]\n                                             compressRatio:0.5\n                                                      name:@\"images\"\n                                                  mimeType:@\"jpg\"\n                                                  progress:^(NSProgress *uploadProgress) {\n\n  self.progressView.observedProgress = uploadProgress;\n\n} success:^(id responseObject) {\n\n} failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode, NSArray\u003cUIImage *\u003e *uploadFailedImages) {\n                                                    \n}];\n```\n\n\n\n\n\nAnd if the server which is used for uploading is **different from** the server for ordinary requests, you can user this api:\n\n```objective-c\n[[SJNetworkManager sharedManager]  sendUploadImagesRequest:@\"http://uploads.im/api\"\n                                               ignoreBaseUrl:YES\n                                                  parameters:nil\n                                                      images:@[image_1,image_2]\n                                               compressRatio:0.5\n                                                        name:@\"images\"\n                                                    mimeType:@\"jpg\"\n                                                    progress:^(NSProgress *uploadProgress) {\n\n      self.progressView.observedProgress = uploadProgress;\n\n  } success:^(id responseObject) {\n\n  } failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode, NSArray\u003cUIImage *\u003e *uploadFailedImages) {\n\n  }];\n```\n\n\n\n\u003e Here, setting ignoreBaseUrl to be YES, and the request url should be complete download url.\n\n\n\n\n\n### Downloading Function:\n\n\nWe support background downloading(using NSURLSessionDownloadTask object ) and none-background downloading(using NSURLSessionDataTask object) , resumable or none-resumable downloading.\n\n\n\n|                            | resumable | none-resumable |\n| -------------------------- | --------- | -------------- |\n| background supporting      | ✅         | ✅              |\n| none-background supporting | ✅         | ✅              |\n\n\n\n\u003e **Note**:If a none-background supporting downloading is on going then app enters into background, the downloading task will be canceled. And When app enters into foreground again, an ``auto-resume mechanism`` will make the downloading task restart again.\n\n\n\n\n\n#### Sending download request\n\n\n\nResumable \u0026\u0026 none-background supporting download reqeust (default configuration):\n\n```objective-c\n[[SJNetworkManager sharedManager] sendDownloadRequest:@\"wallpaper.jpg\"\n                                     downloadFilePath:_imageFileLocalPath\n                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)\n{\n       self.progressView.progress = progress;\n\n} success:^(id responseObject) {\n\n} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {\n\n}];\n```\n\n\n\nNone-resumable \u0026\u0026 none-background supporting download reqeust:\n\n```objective-c\n[[SJNetworkManager sharedManager] sendDownloadRequest:@\"half-eatch.jpg\"\n                                     downloadFilePath:_imageFileLocalPath\n                                            resumable:NO\n                                    backgroundSupport:NO\n                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress) \n{\n\n    self.progressView.progress = progress;\n\n} success:^(id responseObject) {\n\n} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {\n    \n}];\n```\n\n\n\n\n\nResumable \u0026\u0026 background supporting download request:\n\n```objective-c\n[[SJNetworkManager sharedManager] sendDownloadRequest:@\"universe.jpg\"\n                                     downloadFilePath:_imageFileLocalPath\n                                            resumable:YES\n                                    backgroundSupport:YES\n                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)\n{\n\n    self.progressView.progress = progress;\n\n} success:^(id responseObject) {\n\n} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {\n\n}];\n```\n\n\n\nNone-resumable \u0026\u0026 background supporting download request:\n\n```objective-c\n[[SJNetworkManager sharedManager] sendDownloadRequest:@\"iceberg.jpg\"\n                                     downloadFilePath:_imageFileLocalPath\n                                            resumable:NO\n                                    backgroundSupport:YES\n                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)\n{\n\n    self.progressView.progress = progress;\n\n } success:^(id responseObject) {\n\n } failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {\n\n }];\n```\n\n\n\nAlso supports ignoring base url:\n\n```objective-c\n[[SJNetworkManager sharedManager] sendDownloadRequest:@\"http://oih3a9o4n.bkt.clouddn.com/wallpaper.jpg\"\n                                        ignoreBaseUrl:YES\n                                     downloadFilePath:_imageFileLocalPath\n                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)\n{\n      self.progressView.progress = progress;\n\n} success:^(id responseObject) {\n\n} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {\n\n}];\n```\n\n\n\n#### Suspending download request\n\n\n\nSuspending one download  current request:\n\n```objective-c\n[[SJNetworkManager sharedManager] suspendDownloadRequest:@\"universe.jpg\"];\n```\n\n\n\nSuspending one or more than one current download requests:\n\n```objective-c\n[[SJNetworkManager sharedManager] suspendDownloadRequests:@[@\"universe.jpg\",@\"wallpaper.jpg\"]];\n```\n\n\n\nSuspending all current download requests:\n\n```objective-c\n[[SJNetworkManager sharedManager] suspendAllDownloadRequests];\n```\n\n\n\n#### Resuming download request\n\n\n\nResuming one download  suspended request:\n\n```objective-c\n[[SJNetworkManager sharedManager] resumeDownloadReqeust:@\"universe.jpg\"];\n```\n\n\n\nResuming one or more than one download requests:\n\n```objective-c\n[[SJNetworkManager sharedManager] resumeDownloadReqeusts:@[@\"universe.jpg\",@\"wallpaper.jpg\"]];\n```\n\n\n\nResuming all current suspended requests:\n\n```objective-c\n[[SJNetworkManager sharedManager] resumeAllDownloadRequests];\n```\n\n\n\n\n\n#### Canceling download request\n\n\n\nCanceling one download request:\n\n```objective-c\n[[SJNetworkManager sharedManager] cancelDownloadRequest:@\"universe.jpg\"];\n```\n\n\n\nCanceling one or more than one current download requests:\n\n```objective-c\n[[SJNetworkManager sharedManager] cancelDownloadRequests:@[@\"universe.jpg\",@\"wallpaper.jpg\"]];\n```\n\n\n\nCanceling all current download requests:\n\n```objective-c\n[[SJNetworkManager sharedManager] cancelAllDownloadRequests];\n```\n\n\n\n\n\n### Request Management\n\n\n\n#### Current request(s) Information\n\n\n\nChecking if there is remaining current request(s):\n\n```objective-c\nBOOL remaining =  [[SJNetworkManager sharedManager] remainingCurrentRequests];\nif (remaining) {\n    NSLog(@\"There is remaining request\");\n}\n```\n\n\n\nCalculating count of current request(s):\n\n```objective-c\nNSUInteger count = [[SJNetworkManager sharedManager] currentRequestCount];\nif (count \u003e 0) {\n    NSLog(@\"There is %lu requests\",(unsigned long)count);\n}\n```\n\n\n\nLogging all current request(s)：\n\n```objective-c\n[[SJNetworkManager sharedManager] logAllCurrentRequests];\n```\n\n\n\n#### Canceling request\n\n\n\nCanceling one network request:\n\n```objective-c\n[[SJNetworkManager sharedManager] cancelCurrentRequestWithUrl:@\"toutiao/index\"\n                                                       method:@\"POST\"\n                                                   parameters:@{@\"type\":@\"top\",\n                                                                @\"key\" :@\"0c60\"}];\n```\n\n\n\nCanceling network request(s) with the same url:\n\n```objective-c\n[[SJNetworkManager sharedManager] cancelCurrentRequestWithUrl:@\"toutiao/index\"];\n```\n\n\n\nCanceling network request(s) with the same urls:\n\n```objective-c\n[[SJNetworkManager sharedManager] cancelDownloadRequests:@[@\"toutiao/index\",@\"weixin/query\"]];\n```\n\n\n\nCanceling all current network request(s):\n\n```objective-c\n[[SJNetworkManager sharedManager] cancelAllCurrentRequests];\n```\n\n\n\n \t\n\n### Log Output\n\n\n\nIf debug mode is set to be yes, detail log will be provided:\n\n```objective-c\n[SJNetworkConfig sharedConfig].debugMode = YES;\n```\n\n\n\nLoading cache before sending network request, but cache is expired:\n\n```objective-c\n=========== Load cache info failed, reason:Cache is expired, begin to clear cache...\n=========== Load cache failed: Cache info is invalid \n=========== Failed to load cache, start to sending network request...\n=========== Start requesting...\n=========== url:http://v.juhe.cn/toutiao/index\n=========== method:GET\n=========== parameters:{\n    app_version = 1.0;\n    key = 0c60;\n    platform = iOS;\n    type = top;\n}\n=========== Request succeed! \n=========== Request url:http://v.juhe.cn/toutiao/index\n=========== Response object:{\n  code = 200,\n  msg = \"\",\n  data = {}\n}\n=========== Write cache succeed!\n=========== cache object: {\n  code = 200,\n  msg = \"\",\n  data = {}\n}\n=========== Cache path: /Users/*******/\n=========== Available duration: 180 seconds\n```\n\n\n\n## Acknowledgements\n\n\n\nThanks for these service:\n\n- [JuHe.cn](https://www.juhe.cn/): GET/POST api\n- [Uploads.im](http://uploads.im) : Uploading api\n- [QINIU](https://portal.qiniu.com/): Multimedia cloud server(for downloading files)\n\n\n\nAnd also thanks for these two excellent framework:\n\n- [AFNetworking](https://github.com/AFNetworking/AFNetworking)\n- [YTKNetwork](https://github.com/yuantiku/YTKNetwork)\n\n\n\n\n\n## Lisence\n\nSJNetwork is released under the [MIT License](https://github.com/knightsj/SJNetwork/blob/master/LICENSE).\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknightsj%2Fsjnetwork","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknightsj%2Fsjnetwork","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknightsj%2Fsjnetwork/lists"}