mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-24 14:38:45 +00:00
Merge remote-tracking branch 'origin/master' into bug4584
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
64FDEBDC20D12DCF0086C2F4 /* AFAutoPurgingImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 64FDEBDA20D12DCE0086C2F4 /* AFAutoPurgingImageCache.m */; };
|
||||
64FDEBDD20D12DCF0086C2F4 /* AFImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 64FDEBDB20D12DCE0086C2F4 /* AFImageDownloader.m */; };
|
||||
7F0658FD19F7D6700077FF95 /* ScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F0658FC19F7D6700077FF95 /* ScanViewController.swift */; };
|
||||
7F0658FF19F7EE910077FF95 /* CheckInData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F0658FE19F7EE910077FF95 /* CheckInData.swift */; };
|
||||
7F14A10A1A13B9A6001C1ECB /* _abkhazia.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F14A0041A13B9A6001C1ECB /* _abkhazia.png */; };
|
||||
@@ -385,12 +387,9 @@
|
||||
C8E0BD0D1F39ADAD002FCCA5 /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E0BD0C1F39ADAD002FCCA5 /* KeychainPasswordItem.swift */; };
|
||||
C8E0D3131F59475B001EEF5C /* CheckInTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E0D3121F59475B001EEF5C /* CheckInTableViewController.swift */; };
|
||||
C8F1B1E11D488B6D004C3379 /* Translation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F1B1E01D488B6D004C3379 /* Translation.swift */; };
|
||||
C8F71EDA1D8691F700826DE4 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EA61D8691F700826DE4 /* AFHTTPRequestOperation.m */; };
|
||||
C8F71EDB1D8691F700826DE4 /* AFHTTPRequestOperationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EA81D8691F700826DE4 /* AFHTTPRequestOperationManager.m */; };
|
||||
C8F71EDC1D8691F700826DE4 /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EAA1D8691F700826DE4 /* AFHTTPSessionManager.m */; };
|
||||
C8F71EDD1D8691F700826DE4 /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EAD1D8691F700826DE4 /* AFNetworkReachabilityManager.m */; };
|
||||
C8F71EDE1D8691F700826DE4 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EAF1D8691F700826DE4 /* AFSecurityPolicy.m */; };
|
||||
C8F71EDF1D8691F700826DE4 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EB11D8691F700826DE4 /* AFURLConnectionOperation.m */; };
|
||||
C8F71EE01D8691F700826DE4 /* AFURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EB31D8691F700826DE4 /* AFURLRequestSerialization.m */; };
|
||||
C8F71EE11D8691F700826DE4 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EB51D8691F700826DE4 /* AFURLResponseSerialization.m */; };
|
||||
C8F71EE21D8691F700826DE4 /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EB71D8691F700826DE4 /* AFURLSessionManager.m */; };
|
||||
@@ -402,7 +401,6 @@
|
||||
C8F71EE81D8691F700826DE4 /* TSMarkdownParser.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EC61D8691F700826DE4 /* TSMarkdownParser.m */; };
|
||||
C8F71EE91D8691F700826DE4 /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71EC91D8691F700826DE4 /* AFNetworkActivityIndicatorManager.m */; };
|
||||
C8F71EEA1D8691F700826DE4 /* UIActivityIndicatorView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71ECB1D8691F700826DE4 /* UIActivityIndicatorView+AFNetworking.m */; };
|
||||
C8F71EEB1D8691F700826DE4 /* UIAlertView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71ECD1D8691F700826DE4 /* UIAlertView+AFNetworking.m */; };
|
||||
C8F71EEC1D8691F700826DE4 /* UIButton+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71ECF1D8691F700826DE4 /* UIButton+AFNetworking.m */; };
|
||||
C8F71EED1D8691F700826DE4 /* UIImageView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71ED21D8691F700826DE4 /* UIImageView+AFNetworking.m */; };
|
||||
C8F71EEE1D8691F700826DE4 /* UIProgressView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F71ED51D8691F700826DE4 /* UIProgressView+AFNetworking.m */; };
|
||||
@@ -423,6 +421,10 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
64FDEBD220D12C390086C2F4 /* AFImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFImageDownloader.h; sourceTree = "<group>"; };
|
||||
64FDEBD320D12C390086C2F4 /* AFAutoPurgingImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFAutoPurgingImageCache.h; sourceTree = "<group>"; };
|
||||
64FDEBDA20D12DCE0086C2F4 /* AFAutoPurgingImageCache.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFAutoPurgingImageCache.m; sourceTree = "<group>"; };
|
||||
64FDEBDB20D12DCE0086C2F4 /* AFImageDownloader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFImageDownloader.m; sourceTree = "<group>"; };
|
||||
7F03FD3F19FA4D7400FA1327 /* bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = "<group>"; };
|
||||
7F0658FC19F7D6700077FF95 /* ScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ScanViewController.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
7F0658FE19F7EE910077FF95 /* CheckInData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CheckInData.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
@@ -809,10 +811,6 @@
|
||||
C8E0BD0C1F39ADAD002FCCA5 /* KeychainPasswordItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainPasswordItem.swift; sourceTree = "<group>"; };
|
||||
C8E0D3121F59475B001EEF5C /* CheckInTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckInTableViewController.swift; sourceTree = "<group>"; };
|
||||
C8F1B1E01D488B6D004C3379 /* Translation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Translation.swift; sourceTree = "<group>"; };
|
||||
C8F71EA51D8691F700826DE4 /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperation.h; sourceTree = "<group>"; };
|
||||
C8F71EA61D8691F700826DE4 /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperation.m; sourceTree = "<group>"; };
|
||||
C8F71EA71D8691F700826DE4 /* AFHTTPRequestOperationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperationManager.h; sourceTree = "<group>"; };
|
||||
C8F71EA81D8691F700826DE4 /* AFHTTPRequestOperationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperationManager.m; sourceTree = "<group>"; };
|
||||
C8F71EA91D8691F700826DE4 /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPSessionManager.h; sourceTree = "<group>"; };
|
||||
C8F71EAA1D8691F700826DE4 /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPSessionManager.m; sourceTree = "<group>"; };
|
||||
C8F71EAB1D8691F700826DE4 /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = "<group>"; };
|
||||
@@ -820,8 +818,6 @@
|
||||
C8F71EAD1D8691F700826DE4 /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkReachabilityManager.m; sourceTree = "<group>"; };
|
||||
C8F71EAE1D8691F700826DE4 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSecurityPolicy.h; sourceTree = "<group>"; };
|
||||
C8F71EAF1D8691F700826DE4 /* AFSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSecurityPolicy.m; sourceTree = "<group>"; };
|
||||
C8F71EB01D8691F700826DE4 /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLConnectionOperation.h; sourceTree = "<group>"; };
|
||||
C8F71EB11D8691F700826DE4 /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperation.m; sourceTree = "<group>"; };
|
||||
C8F71EB21D8691F700826DE4 /* AFURLRequestSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLRequestSerialization.h; sourceTree = "<group>"; };
|
||||
C8F71EB31D8691F700826DE4 /* AFURLRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLRequestSerialization.m; sourceTree = "<group>"; };
|
||||
C8F71EB41D8691F700826DE4 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLResponseSerialization.h; sourceTree = "<group>"; };
|
||||
@@ -845,8 +841,6 @@
|
||||
C8F71EC91D8691F700826DE4 /* AFNetworkActivityIndicatorManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkActivityIndicatorManager.m; sourceTree = "<group>"; };
|
||||
C8F71ECA1D8691F700826DE4 /* UIActivityIndicatorView+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActivityIndicatorView+AFNetworking.h"; sourceTree = "<group>"; };
|
||||
C8F71ECB1D8691F700826DE4 /* UIActivityIndicatorView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActivityIndicatorView+AFNetworking.m"; sourceTree = "<group>"; };
|
||||
C8F71ECC1D8691F700826DE4 /* UIAlertView+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+AFNetworking.h"; sourceTree = "<group>"; };
|
||||
C8F71ECD1D8691F700826DE4 /* UIAlertView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+AFNetworking.m"; sourceTree = "<group>"; };
|
||||
C8F71ECE1D8691F700826DE4 /* UIButton+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+AFNetworking.h"; sourceTree = "<group>"; };
|
||||
C8F71ECF1D8691F700826DE4 /* UIButton+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+AFNetworking.m"; sourceTree = "<group>"; };
|
||||
C8F71ED01D8691F700826DE4 /* UIImage+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+AFNetworking.h"; sourceTree = "<group>"; };
|
||||
@@ -1565,10 +1559,6 @@
|
||||
C8F71EA41D8691F700826DE4 /* AFNetworking */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C8F71EA51D8691F700826DE4 /* AFHTTPRequestOperation.h */,
|
||||
C8F71EA61D8691F700826DE4 /* AFHTTPRequestOperation.m */,
|
||||
C8F71EA71D8691F700826DE4 /* AFHTTPRequestOperationManager.h */,
|
||||
C8F71EA81D8691F700826DE4 /* AFHTTPRequestOperationManager.m */,
|
||||
C8F71EA91D8691F700826DE4 /* AFHTTPSessionManager.h */,
|
||||
C8F71EAA1D8691F700826DE4 /* AFHTTPSessionManager.m */,
|
||||
C8F71EAB1D8691F700826DE4 /* AFNetworking.h */,
|
||||
@@ -1576,8 +1566,6 @@
|
||||
C8F71EAD1D8691F700826DE4 /* AFNetworkReachabilityManager.m */,
|
||||
C8F71EAE1D8691F700826DE4 /* AFSecurityPolicy.h */,
|
||||
C8F71EAF1D8691F700826DE4 /* AFSecurityPolicy.m */,
|
||||
C8F71EB01D8691F700826DE4 /* AFURLConnectionOperation.h */,
|
||||
C8F71EB11D8691F700826DE4 /* AFURLConnectionOperation.m */,
|
||||
C8F71EB21D8691F700826DE4 /* AFURLRequestSerialization.h */,
|
||||
C8F71EB31D8691F700826DE4 /* AFURLRequestSerialization.m */,
|
||||
C8F71EB41D8691F700826DE4 /* AFURLResponseSerialization.h */,
|
||||
@@ -1618,12 +1606,14 @@
|
||||
C8F71EC71D8691F700826DE4 /* UIKit+AFNetworking */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
64FDEBDA20D12DCE0086C2F4 /* AFAutoPurgingImageCache.m */,
|
||||
64FDEBD320D12C390086C2F4 /* AFAutoPurgingImageCache.h */,
|
||||
64FDEBDB20D12DCE0086C2F4 /* AFImageDownloader.m */,
|
||||
64FDEBD220D12C390086C2F4 /* AFImageDownloader.h */,
|
||||
C8F71EC81D8691F700826DE4 /* AFNetworkActivityIndicatorManager.h */,
|
||||
C8F71EC91D8691F700826DE4 /* AFNetworkActivityIndicatorManager.m */,
|
||||
C8F71ECA1D8691F700826DE4 /* UIActivityIndicatorView+AFNetworking.h */,
|
||||
C8F71ECB1D8691F700826DE4 /* UIActivityIndicatorView+AFNetworking.m */,
|
||||
C8F71ECC1D8691F700826DE4 /* UIAlertView+AFNetworking.h */,
|
||||
C8F71ECD1D8691F700826DE4 /* UIAlertView+AFNetworking.m */,
|
||||
C8F71ECE1D8691F700826DE4 /* UIButton+AFNetworking.h */,
|
||||
C8F71ECF1D8691F700826DE4 /* UIButton+AFNetworking.m */,
|
||||
C8F71ED01D8691F700826DE4 /* UIImage+AFNetworking.h */,
|
||||
@@ -2034,14 +2024,14 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
64FDEBDC20D12DCF0086C2F4 /* AFAutoPurgingImageCache.m in Sources */,
|
||||
64FDEBDD20D12DCF0086C2F4 /* AFImageDownloader.m in Sources */,
|
||||
C867BD091F4B0274007E78E0 /* TrainingCompetitorViewController.swift in Sources */,
|
||||
C85DB82A1F31AAFD009559CE /* LoginViewController.swift in Sources */,
|
||||
C8F71EDA1D8691F700826DE4 /* AFHTTPRequestOperation.m in Sources */,
|
||||
7F1875B31A10F1B800C25BE0 /* TrackingViewController.swift in Sources */,
|
||||
C8739E081D2AA2A500A89F3C /* Leaderboard+CoreDataProperties.swift in Sources */,
|
||||
C8739E121D2BF14F00A89F3C /* EventData.swift in Sources */,
|
||||
C843D4881EBCADDC00250F01 /* CompetitorSessionController.swift in Sources */,
|
||||
C8F71EDF1D8691F700826DE4 /* AFURLConnectionOperation.m in Sources */,
|
||||
C880646E2087DA1F005FBE57 /* BoatClassData.swift in Sources */,
|
||||
C891887A2057F55100E37CC3 /* BoatSessionController.swift in Sources */,
|
||||
C8F71EE31D8691F700826DE4 /* SVIndefiniteAnimatedView.m in Sources */,
|
||||
@@ -2090,7 +2080,6 @@
|
||||
C89C5FCA1D06CECD002AAAD2 /* TrackingViewStatusCell.swift in Sources */,
|
||||
C843D4861EBC927800250F01 /* RegattaMarkViewController.swift in Sources */,
|
||||
C8F71EDE1D8691F700826DE4 /* AFSecurityPolicy.m in Sources */,
|
||||
C8F71EDB1D8691F700826DE4 /* AFHTTPRequestOperationManager.m in Sources */,
|
||||
7F8B8D3F1A37356C00C34B88 /* TrackingPageViewController.swift in Sources */,
|
||||
C89188712057E7D700E37CC3 /* BoatCheckIn.swift in Sources */,
|
||||
C843D48F1EC099EB00250F01 /* CoreData2-3.xcmappingmodel in Sources */,
|
||||
@@ -2143,7 +2132,6 @@
|
||||
C8B3B9C21F3C6B3900B3B6BA /* SignUpTranslation.swift in Sources */,
|
||||
7F950A911A35E967003C8C5C /* LeaderboardViewController.swift in Sources */,
|
||||
C8F71EED1D8691F700826DE4 /* UIImageView+AFNetworking.m in Sources */,
|
||||
C8F71EEB1D8691F700826DE4 /* UIAlertView+AFNetworking.m in Sources */,
|
||||
C88F6D2D1FEACC5700A616BE /* LeaderboardGroupData.swift in Sources */,
|
||||
C87A74EA1F5053AE003DE396 /* RegattaCompetitorCreateAndAddData.swift in Sources */,
|
||||
C8E0D3131F59475B001EEF5C /* CheckInTableViewController.swift in Sources */,
|
||||
|
||||
@@ -85,12 +85,12 @@ class CheckInRequestManager: NSObject {
|
||||
}
|
||||
|
||||
let baseURLString: String
|
||||
let manager: AFHTTPRequestOperationManager
|
||||
let manager: AFHTTPSessionManager
|
||||
let sessionManager: AFURLSessionManager
|
||||
|
||||
init(baseURLString: String = "") {
|
||||
self.baseURLString = baseURLString
|
||||
manager = AFHTTPRequestOperationManager(baseURL: URL(string: baseURLString))
|
||||
manager = AFHTTPSessionManager(baseURL: URL(string: baseURLString))
|
||||
manager.requestSerializer = AFJSONRequestSerializer() as AFHTTPRequestSerializer
|
||||
manager.requestSerializer.timeoutInterval = Application.RequestTimeout
|
||||
manager.responseSerializer = AFJSONResponseSerializer() as AFHTTPResponseSerializer
|
||||
@@ -111,6 +111,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.get(
|
||||
urlString,
|
||||
parameters: nil,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.getEventSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.getEventFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -138,6 +139,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.get(
|
||||
urlString,
|
||||
parameters: nil,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.getLeaderboardSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.getLeaderboardFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -165,6 +167,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.get(
|
||||
urlString,
|
||||
parameters: nil,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.getBoatSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.getBoatFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -192,6 +195,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.get(
|
||||
urlString,
|
||||
parameters: nil,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.getCompetitorSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.getCompetitorFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -221,6 +225,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.get(
|
||||
urlString,
|
||||
parameters: nil,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.getMarkSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.getMarkFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -248,6 +253,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.get(
|
||||
urlString,
|
||||
parameters: nil,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.getTeamSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.getTeamFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -301,6 +307,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.post(
|
||||
urlString,
|
||||
parameters: body,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.postCheckInSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.postCheckInFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -340,6 +347,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.post(
|
||||
urlString,
|
||||
parameters: body,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.postCheckOutSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.postCheckOutFailure(error: error, failure: failure) }
|
||||
)
|
||||
@@ -381,6 +389,7 @@ class CheckInRequestManager: NSObject {
|
||||
manager.post(
|
||||
urlString,
|
||||
parameters: body,
|
||||
progress: nil,
|
||||
success: { (requestOperation, responseObject) in self.postGPSFixesSuccess(responseObject: responseObject, success: success) },
|
||||
failure: { (requestOperation, error) in self.postGPSFixesFailure(error: error, failure: failure) }
|
||||
)
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
// AFHTTPRequestOperation.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "AFURLConnectionOperation.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
|
||||
*/
|
||||
@interface AFHTTPRequestOperation : AFURLConnectionOperation
|
||||
|
||||
///------------------------------------------------
|
||||
/// @name Getting HTTP URL Connection Information
|
||||
///------------------------------------------------
|
||||
|
||||
/**
|
||||
The last HTTP response received by the operation's connection.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong, nullable) NSHTTPURLResponse *response;
|
||||
|
||||
/**
|
||||
Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an AFHTTPResponse serializer, which uses the raw data as its response object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed.
|
||||
|
||||
@warning `responseSerializer` must not be `nil`. Setting a response serializer will clear out any cached value
|
||||
*/
|
||||
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;
|
||||
|
||||
/**
|
||||
An object constructed by the `responseSerializer` from the response and response data. Returns `nil` unless the operation `isFinished`, has a `response`, and has `responseData` with non-zero content length. If an error occurs during serialization, `nil` will be returned, and the `error` property will be populated with the serialization error.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong, nullable) id responseObject;
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Setting Completion Block Success / Failure Callbacks
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed.
|
||||
|
||||
This method should be overridden in subclasses in order to specify the response object passed into the success block.
|
||||
|
||||
@param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request.
|
||||
@param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request.
|
||||
*/
|
||||
- (void)setCompletionBlockWithSuccess:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,206 +0,0 @@
|
||||
// AFHTTPRequestOperation.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
|
||||
static dispatch_queue_t http_request_operation_processing_queue() {
|
||||
static dispatch_queue_t af_http_request_operation_processing_queue;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
af_http_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.http-request.processing", DISPATCH_QUEUE_CONCURRENT);
|
||||
});
|
||||
|
||||
return af_http_request_operation_processing_queue;
|
||||
}
|
||||
|
||||
static dispatch_group_t http_request_operation_completion_group() {
|
||||
static dispatch_group_t af_http_request_operation_completion_group;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
af_http_request_operation_completion_group = dispatch_group_create();
|
||||
});
|
||||
|
||||
return af_http_request_operation_completion_group;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface AFURLConnectionOperation ()
|
||||
@property (readwrite, nonatomic, strong) NSURLRequest *request;
|
||||
@property (readwrite, nonatomic, strong) NSURLResponse *response;
|
||||
@end
|
||||
|
||||
@interface AFHTTPRequestOperation ()
|
||||
@property (readwrite, nonatomic, strong) NSHTTPURLResponse *response;
|
||||
@property (readwrite, nonatomic, strong) id responseObject;
|
||||
@property (readwrite, nonatomic, strong) NSError *responseSerializationError;
|
||||
@property (readwrite, nonatomic, strong) NSRecursiveLock *lock;
|
||||
@end
|
||||
|
||||
@implementation AFHTTPRequestOperation
|
||||
@dynamic response;
|
||||
@dynamic lock;
|
||||
|
||||
- (instancetype)initWithRequest:(NSURLRequest *)urlRequest {
|
||||
self = [super initWithRequest:urlRequest];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setResponseSerializer:(AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer {
|
||||
NSParameterAssert(responseSerializer);
|
||||
|
||||
[self.lock lock];
|
||||
_responseSerializer = responseSerializer;
|
||||
self.responseObject = nil;
|
||||
self.responseSerializationError = nil;
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (id)responseObject {
|
||||
[self.lock lock];
|
||||
if (!_responseObject && [self isFinished] && !self.error) {
|
||||
NSError *error = nil;
|
||||
self.responseObject = [self.responseSerializer responseObjectForResponse:self.response data:self.responseData error:&error];
|
||||
if (error) {
|
||||
self.responseSerializationError = error;
|
||||
}
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseObject;
|
||||
}
|
||||
|
||||
- (NSError *)error {
|
||||
if (_responseSerializationError) {
|
||||
return _responseSerializationError;
|
||||
} else {
|
||||
return [super error];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - AFHTTPRequestOperation
|
||||
|
||||
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
// completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-retain-cycles"
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
self.completionBlock = ^{
|
||||
if (self.completionGroup) {
|
||||
dispatch_group_enter(self.completionGroup);
|
||||
}
|
||||
|
||||
dispatch_async(http_request_operation_processing_queue(), ^{
|
||||
if (self.error) {
|
||||
if (failure) {
|
||||
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||
failure(self, self.error);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
id responseObject = self.responseObject;
|
||||
if (self.error) {
|
||||
if (failure) {
|
||||
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||
failure(self, self.error);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (success) {
|
||||
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||
success(self, responseObject);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self.completionGroup) {
|
||||
dispatch_group_leave(self.completionGroup);
|
||||
}
|
||||
});
|
||||
};
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
#pragma mark - AFURLRequestOperation
|
||||
|
||||
- (void)pause {
|
||||
[super pause];
|
||||
|
||||
u_int64_t offset = 0;
|
||||
if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) {
|
||||
offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue];
|
||||
} else {
|
||||
offset = [(NSData *)[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length];
|
||||
}
|
||||
|
||||
NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy];
|
||||
if ([self.response respondsToSelector:@selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:@"ETag"]) {
|
||||
[mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"];
|
||||
}
|
||||
[mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];
|
||||
self.request = mutableURLRequest;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||
[super encodeWithCoder:coder];
|
||||
|
||||
[coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
AFHTTPRequestOperation *operation = [super copyWithZone:zone];
|
||||
|
||||
operation.responseSerializer = [self.responseSerializer copyWithZone:zone];
|
||||
operation.completionQueue = self.completionQueue;
|
||||
operation.completionGroup = self.completionGroup;
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
@end
|
||||
-326
@@ -1,326 +0,0 @@
|
||||
// AFHTTPRequestOperationManager.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#import <Availability.h>
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
#else
|
||||
#import <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
#import "AFURLRequestSerialization.h"
|
||||
#import "AFSecurityPolicy.h"
|
||||
#import "AFNetworkReachabilityManager.h"
|
||||
|
||||
#ifndef NS_DESIGNATED_INITIALIZER
|
||||
#if __has_attribute(objc_designated_initializer)
|
||||
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
#else
|
||||
#define NS_DESIGNATED_INITIALIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
`AFHTTPRequestOperationManager` encapsulates the common patterns of communicating with a web application over HTTP, including request creation, response serialization, network reachability monitoring, and security, as well as request operation management.
|
||||
|
||||
## Subclassing Notes
|
||||
|
||||
Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application.
|
||||
|
||||
For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect.
|
||||
|
||||
## Methods to Override
|
||||
|
||||
To change the behavior of all request operation construction for an `AFHTTPRequestOperationManager` subclass, override `HTTPRequestOperationWithRequest:success:failure`.
|
||||
|
||||
## Serialization
|
||||
|
||||
Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to `<AFURLRequestSerialization>`.
|
||||
|
||||
Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `<AFURLResponseSerialization>`
|
||||
|
||||
## URL Construction Using Relative Paths
|
||||
|
||||
For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`.
|
||||
|
||||
Below are a few examples of how `baseURL` and relative paths interact:
|
||||
|
||||
NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];
|
||||
[NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo
|
||||
[NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz
|
||||
[NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo
|
||||
[NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo
|
||||
[NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/
|
||||
[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
|
||||
|
||||
Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash.
|
||||
|
||||
## Network Reachability Monitoring
|
||||
|
||||
Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details.
|
||||
|
||||
## NSSecureCoding & NSCopying Caveats
|
||||
|
||||
`AFHTTPRequestOperationManager` conforms to the `NSSecureCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. There are a few minor caveats to keep in mind, however:
|
||||
|
||||
- Archives and copies of HTTP clients will be initialized with an empty operation queue.
|
||||
- NSSecureCoding cannot serialize / deserialize block properties, so an archive of an HTTP client will not include any reachability callback block that may be set.
|
||||
*/
|
||||
@interface AFHTTPRequestOperationManager : NSObject <NSSecureCoding, NSCopying>
|
||||
|
||||
/**
|
||||
The URL used to monitor reachability, and construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong, nullable) NSURL *baseURL;
|
||||
|
||||
/**
|
||||
Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies.
|
||||
|
||||
@warning `requestSerializer` must not be `nil`.
|
||||
*/
|
||||
@property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer;
|
||||
|
||||
/**
|
||||
Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to a JSON serializer, which serializes data from responses with a `application/json` MIME type, and falls back to the raw data object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed.
|
||||
|
||||
@warning `responseSerializer` must not be `nil`.
|
||||
*/
|
||||
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;
|
||||
|
||||
/**
|
||||
The operation queue on which request operations are scheduled and run.
|
||||
*/
|
||||
@property (nonatomic, strong) NSOperationQueue *operationQueue;
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing URL Credentials
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
Whether request operations should consult the credential storage for authenticating the connection. `YES` by default.
|
||||
|
||||
@see AFURLConnectionOperation -shouldUseCredentialStorage
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldUseCredentialStorage;
|
||||
|
||||
/**
|
||||
The credential used by request operations for authentication challenges.
|
||||
|
||||
@see AFURLConnectionOperation -credential
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) NSURLCredential *credential;
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing Security Policy
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
The security policy used by created request operations to evaluate server trust for secure connections. `AFHTTPRequestOperationManager` uses the `defaultPolicy` unless otherwise specified.
|
||||
*/
|
||||
@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;
|
||||
|
||||
///------------------------------------
|
||||
/// @name Managing Network Reachability
|
||||
///------------------------------------
|
||||
|
||||
/**
|
||||
The network reachability manager. `AFHTTPRequestOperationManager` uses the `sharedManager` by default.
|
||||
*/
|
||||
@property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager;
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing Callback Queues
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
The dispatch queue for the `completionBlock` of request operations. If `NULL` (default), the main queue is used.
|
||||
*/
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
@property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;
|
||||
#else
|
||||
@property (nonatomic, assign, nullable) dispatch_queue_t completionQueue;
|
||||
#endif
|
||||
|
||||
/**
|
||||
The dispatch group for the `completionBlock` of request operations. If `NULL` (default), a private dispatch group is used.
|
||||
*/
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
@property (nonatomic, strong, nullable) dispatch_group_t completionGroup;
|
||||
#else
|
||||
@property (nonatomic, assign, nullable) dispatch_group_t completionGroup;
|
||||
#endif
|
||||
|
||||
///---------------------------------------------
|
||||
/// @name Creating and Initializing HTTP Clients
|
||||
///---------------------------------------------
|
||||
|
||||
/**
|
||||
Creates and returns an `AFHTTPRequestOperationManager` object.
|
||||
*/
|
||||
+ (instancetype)manager;
|
||||
|
||||
/**
|
||||
Initializes an `AFHTTPRequestOperationManager` object with the specified base URL.
|
||||
|
||||
This is the designated initializer.
|
||||
|
||||
@param url The base URL for the HTTP client.
|
||||
|
||||
@return The newly-initialized HTTP client
|
||||
*/
|
||||
- (instancetype)initWithBaseURL:(nullable NSURL *)url NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
///---------------------------------------
|
||||
/// @name Managing HTTP Request Operations
|
||||
///---------------------------------------
|
||||
|
||||
/**
|
||||
Creates an `AFHTTPRequestOperation`, and sets the response serializers to that of the HTTP client.
|
||||
|
||||
@param request The request object to be loaded asynchronously during execution of the operation.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the object created from the response data of request.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred.
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
///---------------------------
|
||||
/// @name Making HTTP Requests
|
||||
///---------------------------
|
||||
|
||||
/**
|
||||
Creates and runs an `AFHTTPRequestOperation` with a `GET` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (nullable AFHTTPRequestOperation *)GET:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation * __nullable operation, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `AFHTTPRequestOperation` with a `HEAD` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes a single arguments: the request operation.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (nullable AFHTTPRequestOperation *)HEAD:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation * __nullable operation, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `AFHTTPRequestOperation` with a `POST` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (nullable AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation * __nullable operation, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `AFHTTPRequestOperation` with a multipart `POST` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (nullable AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation * __nullable operation, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `AFHTTPRequestOperation` with a `PUT` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (nullable AFHTTPRequestOperation *)PUT:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation * __nullable operation, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `AFHTTPRequestOperation` with a `PATCH` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (nullable AFHTTPRequestOperation *)PATCH:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation * __nullable operation, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `AFHTTPRequestOperation` with a `DELETE` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (nullable AFHTTPRequestOperation *)DELETE:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(nullable void (^)(AFHTTPRequestOperation * __nullable operation, NSError *error))failure;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-290
@@ -1,290 +0,0 @@
|
||||
// AFHTTPRequestOperationManager.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "AFHTTPRequestOperationManager.h"
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
|
||||
#import <Availability.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
@interface AFHTTPRequestOperationManager ()
|
||||
@property (readwrite, nonatomic, strong) NSURL *baseURL;
|
||||
@end
|
||||
|
||||
@implementation AFHTTPRequestOperationManager
|
||||
|
||||
+ (instancetype)manager {
|
||||
return [[self alloc] initWithBaseURL:nil];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithBaseURL:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithBaseURL:(NSURL *)url {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
|
||||
if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
|
||||
url = [url URLByAppendingPathComponent:@""];
|
||||
}
|
||||
|
||||
self.baseURL = url;
|
||||
|
||||
self.requestSerializer = [AFHTTPRequestSerializer serializer];
|
||||
self.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
|
||||
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
|
||||
|
||||
self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
|
||||
|
||||
self.operationQueue = [[NSOperationQueue alloc] init];
|
||||
|
||||
self.shouldUseCredentialStorage = YES;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
#endif
|
||||
|
||||
- (void)setRequestSerializer:(AFHTTPRequestSerializer <AFURLRequestSerialization> *)requestSerializer {
|
||||
NSParameterAssert(requestSerializer);
|
||||
|
||||
_requestSerializer = requestSerializer;
|
||||
}
|
||||
|
||||
- (void)setResponseSerializer:(AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer {
|
||||
NSParameterAssert(responseSerializer);
|
||||
|
||||
_responseSerializer = responseSerializer;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (AFHTTPRequestOperation *)HTTPRequestOperationWithHTTPMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSError *serializationError = nil;
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
|
||||
if (serializationError) {
|
||||
if (failure) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||
failure(nil, serializationError);
|
||||
});
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
|
||||
operation.responseSerializer = self.responseSerializer;
|
||||
operation.shouldUseCredentialStorage = self.shouldUseCredentialStorage;
|
||||
operation.credential = self.credential;
|
||||
operation.securityPolicy = self.securityPolicy;
|
||||
|
||||
[operation setCompletionBlockWithSuccess:success failure:failure];
|
||||
operation.completionQueue = self.completionQueue;
|
||||
operation.completionGroup = self.completionGroup;
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (AFHTTPRequestOperation *)GET:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)HEAD:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters success:^(AFHTTPRequestOperation *requestOperation, __unused id responseObject) {
|
||||
if (success) {
|
||||
success(requestOperation);
|
||||
}
|
||||
} failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSError *serializationError = nil;
|
||||
NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];
|
||||
if (serializationError) {
|
||||
if (failure) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||
failure(nil, serializationError);
|
||||
});
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)PUT:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)PATCH:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)DELETE:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.operationQueue];
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
NSURL *baseURL = [decoder decodeObjectForKey:NSStringFromSelector(@selector(baseURL))];
|
||||
|
||||
self = [self initWithBaseURL:baseURL];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))];
|
||||
self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
AFSecurityPolicy *decodedPolicy = [decoder decodeObjectOfClass:[AFSecurityPolicy class] forKey:NSStringFromSelector(@selector(securityPolicy))];
|
||||
if (decodedPolicy) {
|
||||
self.securityPolicy = decodedPolicy;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||
[coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))];
|
||||
[coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))];
|
||||
[coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
[coder encodeObject:self.securityPolicy forKey:NSStringFromSelector(@selector(securityPolicy))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
AFHTTPRequestOperationManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL];
|
||||
|
||||
HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone];
|
||||
HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone];
|
||||
HTTPClient.securityPolicy = [self.securityPolicy copyWithZone:zone];
|
||||
|
||||
return HTTPClient;
|
||||
}
|
||||
|
||||
@end
|
||||
Regular → Executable
+70
-28
@@ -1,5 +1,5 @@
|
||||
// AFHTTPSessionManager.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,9 +23,9 @@
|
||||
#if !TARGET_OS_WATCH
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#endif
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
#if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
#else
|
||||
#import <CoreServices/CoreServices.h>
|
||||
@@ -33,14 +33,6 @@
|
||||
|
||||
#import "AFURLSessionManager.h"
|
||||
|
||||
#ifndef NS_DESIGNATED_INITIALIZER
|
||||
#if __has_attribute(objc_designated_initializer)
|
||||
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
#else
|
||||
#define NS_DESIGNATED_INITIALIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
`AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths.
|
||||
|
||||
@@ -79,8 +71,6 @@
|
||||
@warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance.
|
||||
*/
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || TARGET_OS_WATCH
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AFHTTPSessionManager : AFURLSessionManager <NSSecureCoding, NSCopying>
|
||||
@@ -151,8 +141,26 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * __nullable task, NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
|
||||
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a `GET` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param downloadProgress A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a `HEAD` request.
|
||||
@@ -167,7 +175,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * __nullable task, NSError *error))failure;
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a `POST` request.
|
||||
@@ -181,8 +189,25 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * __nullable task, NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a `POST` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request.
|
||||
@@ -198,8 +223,27 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * __nullable task, NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request.
|
||||
|
||||
@param URLString The URL string used to create the request URL.
|
||||
@param parameters The parameters to be encoded according to the client request serializer.
|
||||
@param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol.
|
||||
@param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
|
||||
@param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
|
||||
|
||||
@see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
|
||||
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a `PUT` request.
|
||||
@@ -213,8 +257,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * __nullable task, NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a `PATCH` request.
|
||||
@@ -228,8 +272,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * __nullable task, NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates and runs an `NSURLSessionDataTask` with a `DELETE` request.
|
||||
@@ -243,11 +287,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * __nullable task, NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
|
||||
Regular → Executable
+54
-21
@@ -1,5 +1,5 @@
|
||||
// AFHTTPSessionManager.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,23 +21,20 @@
|
||||
|
||||
#import "AFHTTPSessionManager.h"
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || TARGET_WATCH_OS
|
||||
|
||||
#import "AFURLRequestSerialization.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
#import <netinet/in.h>
|
||||
#import <netinet6/in6.h>
|
||||
#import <arpa/inet.h>
|
||||
#import <ifaddrs.h>
|
||||
#import <netdb.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
#import <UIKit/UIKit.h>
|
||||
#elif TARGET_OS_WATCH
|
||||
#import <WatchKit/WatchKit.h>
|
||||
@@ -89,9 +86,6 @@
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
#endif
|
||||
|
||||
- (void)setRequestSerializer:(AFHTTPRequestSerializer <AFURLRequestSerialization> *)requestSerializer {
|
||||
NSParameterAssert(requestSerializer);
|
||||
|
||||
@@ -111,7 +105,24 @@
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
return [self GET:URLString parameters:parameters progress:nil success:success failure:failure];
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)GET:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
progress:(void (^)(NSProgress * _Nonnull))downloadProgress
|
||||
success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
|
||||
failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
|
||||
{
|
||||
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
|
||||
URLString:URLString
|
||||
parameters:parameters
|
||||
uploadProgress:nil
|
||||
downloadProgress:downloadProgress
|
||||
success:success
|
||||
failure:failure];
|
||||
|
||||
[dataTask resume];
|
||||
|
||||
@@ -123,7 +134,7 @@
|
||||
success:(void (^)(NSURLSessionDataTask *task))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters success:^(NSURLSessionDataTask *task, __unused id responseObject) {
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) {
|
||||
if (success) {
|
||||
success(task);
|
||||
}
|
||||
@@ -139,16 +150,35 @@
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
return [self POST:URLString parameters:parameters progress:nil success:success failure:failure];
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
progress:(void (^)(NSProgress * _Nonnull))uploadProgress
|
||||
success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
|
||||
failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
|
||||
|
||||
[dataTask resume];
|
||||
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
constructingBodyWithBlock:(nullable void (^)(id<AFMultipartFormData> _Nonnull))block
|
||||
success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
|
||||
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
|
||||
{
|
||||
return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure];
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
|
||||
progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
@@ -167,7 +197,7 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
__block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
__block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(task, error);
|
||||
@@ -189,7 +219,7 @@
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
|
||||
|
||||
[dataTask resume];
|
||||
|
||||
@@ -201,7 +231,7 @@
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
|
||||
|
||||
[dataTask resume];
|
||||
|
||||
@@ -213,7 +243,7 @@
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
|
||||
|
||||
[dataTask resume];
|
||||
|
||||
@@ -223,6 +253,8 @@
|
||||
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
|
||||
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
|
||||
success:(void (^)(NSURLSessionDataTask *, id))success
|
||||
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
|
||||
{
|
||||
@@ -242,7 +274,10 @@
|
||||
}
|
||||
|
||||
__block NSURLSessionDataTask *dataTask = nil;
|
||||
dataTask = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
dataTask = [self dataTaskWithRequest:request
|
||||
uploadProgress:uploadProgress
|
||||
downloadProgress:downloadProgress
|
||||
completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(dataTask, error);
|
||||
@@ -269,7 +304,7 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
NSURL *baseURL = [decoder decodeObjectOfClass:[NSURL class] forKey:NSStringFromSelector(@selector(baseURL))];
|
||||
NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"];
|
||||
if (!configuration) {
|
||||
@@ -314,7 +349,7 @@
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFHTTPSessionManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL sessionConfiguration:self.session.configuration];
|
||||
|
||||
HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone];
|
||||
@@ -324,5 +359,3 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
Regular → Executable
+10
-11
@@ -1,5 +1,5 @@
|
||||
// AFNetworkReachabilityManager.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,14 +24,6 @@
|
||||
#if !TARGET_OS_WATCH
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
#ifndef NS_DESIGNATED_INITIALIZER
|
||||
#if __has_attribute(objc_designated_initializer)
|
||||
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
#else
|
||||
#define NS_DESIGNATED_INITIALIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
|
||||
AFNetworkReachabilityStatusUnknown = -1,
|
||||
AFNetworkReachabilityStatusNotReachable = 0,
|
||||
@@ -46,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability.
|
||||
|
||||
See Apple's Reachability Sample Code (https://developer.apple.com/library/ios/samplecode/reachability/)
|
||||
See Apple's Reachability Sample Code ( https://developer.apple.com/library/ios/samplecode/reachability/ )
|
||||
|
||||
@warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
|
||||
*/
|
||||
@@ -81,6 +73,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
/**
|
||||
Creates and returns a network reachability manager with the default socket address.
|
||||
|
||||
@return An initialized network reachability manager, actively monitoring the default socket address.
|
||||
*/
|
||||
+ (instancetype)manager;
|
||||
|
||||
/**
|
||||
Creates and returns a network reachability manager for the specified domain.
|
||||
|
||||
@@ -93,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
Creates and returns a network reachability manager for the socket address.
|
||||
|
||||
@param address The socket address (`sockaddr_in`) used to evaluate network reachability.
|
||||
@param address The socket address (`sockaddr_in6`) used to evaluate network reachability.
|
||||
|
||||
@return An initialized network reachability manager, actively monitoring the specified socket address.
|
||||
*/
|
||||
|
||||
Regular → Executable
+32
-17
@@ -1,5 +1,5 @@
|
||||
// AFNetworkReachabilityManager.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -94,6 +94,7 @@ static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused targ
|
||||
AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusBlock)info);
|
||||
}
|
||||
|
||||
|
||||
static const void * AFNetworkReachabilityRetainCallback(const void *info) {
|
||||
return Block_copy(info);
|
||||
}
|
||||
@@ -105,7 +106,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
}
|
||||
|
||||
@interface AFNetworkReachabilityManager ()
|
||||
@property (readwrite, nonatomic, strong) id networkReachability;
|
||||
@property (readonly, nonatomic, assign) SCNetworkReachabilityRef networkReachability;
|
||||
@property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus;
|
||||
@property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock;
|
||||
@end
|
||||
@@ -116,35 +117,46 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
static AFNetworkReachabilityManager *_sharedManager = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
struct sockaddr_in address;
|
||||
bzero(&address, sizeof(address));
|
||||
address.sin_len = sizeof(address);
|
||||
address.sin_family = AF_INET;
|
||||
|
||||
_sharedManager = [self managerForAddress:&address];
|
||||
_sharedManager = [self manager];
|
||||
});
|
||||
|
||||
return _sharedManager;
|
||||
}
|
||||
|
||||
#ifndef __clang_analyzer__
|
||||
+ (instancetype)managerForDomain:(NSString *)domain {
|
||||
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]);
|
||||
|
||||
AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
|
||||
|
||||
CFRelease(reachability);
|
||||
|
||||
return manager;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __clang_analyzer__
|
||||
+ (instancetype)managerForAddress:(const void *)address {
|
||||
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
|
||||
AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
|
||||
|
||||
CFRelease(reachability);
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
+ (instancetype)manager
|
||||
{
|
||||
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
|
||||
struct sockaddr_in6 address;
|
||||
bzero(&address, sizeof(address));
|
||||
address.sin6_len = sizeof(address);
|
||||
address.sin6_family = AF_INET6;
|
||||
#else
|
||||
struct sockaddr_in address;
|
||||
bzero(&address, sizeof(address));
|
||||
address.sin_len = sizeof(address);
|
||||
address.sin_family = AF_INET;
|
||||
#endif
|
||||
return [self managerForAddress:&address];
|
||||
}
|
||||
|
||||
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
|
||||
self = [super init];
|
||||
@@ -152,7 +164,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.networkReachability = CFBridgingRelease(reachability);
|
||||
_networkReachability = CFRetain(reachability);
|
||||
self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;
|
||||
|
||||
return self;
|
||||
@@ -165,6 +177,10 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
|
||||
- (void)dealloc {
|
||||
[self stopMonitoring];
|
||||
|
||||
if (_networkReachability != NULL) {
|
||||
CFRelease(_networkReachability);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -201,14 +217,13 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
|
||||
};
|
||||
|
||||
id networkReachability = self.networkReachability;
|
||||
SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
|
||||
SCNetworkReachabilitySetCallback((__bridge SCNetworkReachabilityRef)networkReachability, AFNetworkReachabilityCallback, &context);
|
||||
SCNetworkReachabilityScheduleWithRunLoop((__bridge SCNetworkReachabilityRef)networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
|
||||
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
|
||||
SCNetworkReachabilityFlags flags;
|
||||
if (SCNetworkReachabilityGetFlags((__bridge SCNetworkReachabilityRef)networkReachability, &flags)) {
|
||||
if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
|
||||
AFPostReachabilityStatusChange(flags, callback);
|
||||
}
|
||||
});
|
||||
@@ -219,7 +234,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
return;
|
||||
}
|
||||
|
||||
SCNetworkReachabilityUnscheduleFromRunLoop((__bridge SCNetworkReachabilityRef)self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
Regular → Executable
+2
-7
@@ -22,6 +22,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#ifndef _AFNETWORKING_
|
||||
#define _AFNETWORKING_
|
||||
@@ -29,18 +30,12 @@
|
||||
#import "AFURLRequestSerialization.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
#import "AFSecurityPolicy.h"
|
||||
|
||||
#if !TARGET_OS_WATCH
|
||||
#import "AFNetworkReachabilityManager.h"
|
||||
#import "AFURLConnectionOperation.h"
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
#import "AFHTTPRequestOperationManager.h"
|
||||
#endif
|
||||
|
||||
#if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \
|
||||
( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) || \
|
||||
TARGET_OS_WATCH )
|
||||
#import "AFURLSessionManager.h"
|
||||
#import "AFHTTPSessionManager.h"
|
||||
#endif
|
||||
|
||||
#endif /* _AFNETWORKING_ */
|
||||
|
||||
Regular → Executable
+28
-16
@@ -1,5 +1,5 @@
|
||||
// AFSecurityPolicy.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -44,9 +44,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
|
||||
|
||||
/**
|
||||
The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle. Note that if you create an array with duplicate certificates, the duplicate certificates will be removed. Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
|
||||
The certificates used to evaluate server trust according to the SSL pinning mode.
|
||||
|
||||
By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`.
|
||||
|
||||
Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) NSArray *pinnedCertificates;
|
||||
@property (nonatomic, strong, nullable) NSSet <NSData *> *pinnedCertificates;
|
||||
|
||||
/**
|
||||
Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
|
||||
@@ -58,6 +62,17 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL validatesDomainName;
|
||||
|
||||
///-----------------------------------------
|
||||
/// @name Getting Certificates from the Bundle
|
||||
///-----------------------------------------
|
||||
|
||||
/**
|
||||
Returns any certificates included in the bundle. If you are using AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`.
|
||||
|
||||
@return The certificates included in the given bundle.
|
||||
*/
|
||||
+ (NSSet <NSData *> *)certificatesInBundle:(NSBundle *)bundle;
|
||||
|
||||
///-----------------------------------------
|
||||
/// @name Getting Specific Security Policies
|
||||
///-----------------------------------------
|
||||
@@ -82,23 +97,20 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode;
|
||||
|
||||
/**
|
||||
Creates and returns a security policy with the specified pinning mode.
|
||||
|
||||
@param pinningMode The SSL pinning mode.
|
||||
@param pinnedCertificates The certificates to pin against.
|
||||
|
||||
@return A new security policy.
|
||||
*/
|
||||
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet <NSData *> *)pinnedCertificates;
|
||||
|
||||
///------------------------------
|
||||
/// @name Evaluating Server Trust
|
||||
///------------------------------
|
||||
|
||||
/**
|
||||
Whether or not the specified server trust should be accepted, based on the security policy.
|
||||
|
||||
This method should be used when responding to an authentication challenge from a server.
|
||||
|
||||
@param serverTrust The X.509 certificate trust of the server.
|
||||
|
||||
@return Whether or not to trust the server.
|
||||
|
||||
@warning This method has been deprecated in favor of `-evaluateServerTrust:forDomain:`.
|
||||
*/
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
Whether or not the specified server trust should be accepted, based on the security policy.
|
||||
|
||||
|
||||
Regular → Executable
+36
-30
@@ -1,5 +1,5 @@
|
||||
// AFSecurityPolicy.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#import <AssertMacros.h>
|
||||
|
||||
#if !TARGET_OS_IOS && !TARGET_OS_WATCH
|
||||
#if !TARGET_OS_IOS && !TARGET_OS_WATCH && !TARGET_OS_TV
|
||||
static NSData * AFSecKeyGetData(SecKeyRef key) {
|
||||
CFDataRef data = NULL;
|
||||
|
||||
@@ -41,7 +41,7 @@ _out:
|
||||
#endif
|
||||
|
||||
static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) {
|
||||
#if TARGET_OS_IOS || TARGET_OS_WATCH
|
||||
#if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV
|
||||
return [(__bridge id)key1 isEqual:(__bridge id)key2];
|
||||
#else
|
||||
return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)];
|
||||
@@ -150,25 +150,29 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
|
||||
@interface AFSecurityPolicy()
|
||||
@property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
|
||||
@property (readwrite, nonatomic, strong) NSArray *pinnedPublicKeys;
|
||||
@property (readwrite, nonatomic, strong) NSSet *pinnedPublicKeys;
|
||||
@end
|
||||
|
||||
@implementation AFSecurityPolicy
|
||||
|
||||
+ (NSArray *)defaultPinnedCertificates {
|
||||
static NSArray *_defaultPinnedCertificates = nil;
|
||||
+ (NSSet *)certificatesInBundle:(NSBundle *)bundle {
|
||||
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];
|
||||
|
||||
NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]];
|
||||
for (NSString *path in paths) {
|
||||
NSData *certificateData = [NSData dataWithContentsOfFile:path];
|
||||
[certificates addObject:certificateData];
|
||||
}
|
||||
|
||||
return [NSSet setWithSet:certificates];
|
||||
}
|
||||
|
||||
+ (NSSet *)defaultPinnedCertificates {
|
||||
static NSSet *_defaultPinnedCertificates = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
|
||||
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];
|
||||
|
||||
NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[paths count]];
|
||||
for (NSString *path in paths) {
|
||||
NSData *certificateData = [NSData dataWithContentsOfFile:path];
|
||||
[certificates addObject:certificateData];
|
||||
}
|
||||
|
||||
_defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates];
|
||||
_defaultPinnedCertificates = [self certificatesInBundle:bundle];
|
||||
});
|
||||
|
||||
return _defaultPinnedCertificates;
|
||||
@@ -182,15 +186,19 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
}
|
||||
|
||||
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode {
|
||||
return [self policyWithPinningMode:pinningMode withPinnedCertificates:[self defaultPinnedCertificates]];
|
||||
}
|
||||
|
||||
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates {
|
||||
AFSecurityPolicy *securityPolicy = [[self alloc] init];
|
||||
securityPolicy.SSLPinningMode = pinningMode;
|
||||
|
||||
[securityPolicy setPinnedCertificates:[self defaultPinnedCertificates]];
|
||||
[securityPolicy setPinnedCertificates:pinnedCertificates];
|
||||
|
||||
return securityPolicy;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -201,11 +209,11 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setPinnedCertificates:(NSArray *)pinnedCertificates {
|
||||
_pinnedCertificates = [[NSOrderedSet orderedSetWithArray:pinnedCertificates] array];
|
||||
- (void)setPinnedCertificates:(NSSet *)pinnedCertificates {
|
||||
_pinnedCertificates = pinnedCertificates;
|
||||
|
||||
if (self.pinnedCertificates) {
|
||||
NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]];
|
||||
NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]];
|
||||
for (NSData *certificate in self.pinnedCertificates) {
|
||||
id publicKey = AFPublicKeyForCertificate(certificate);
|
||||
if (!publicKey) {
|
||||
@@ -213,7 +221,7 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
}
|
||||
[mutablePinnedPublicKeys addObject:publicKey];
|
||||
}
|
||||
self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys];
|
||||
self.pinnedPublicKeys = [NSSet setWithSet:mutablePinnedPublicKeys];
|
||||
} else {
|
||||
self.pinnedPublicKeys = nil;
|
||||
}
|
||||
@@ -221,10 +229,6 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust {
|
||||
return [self evaluateServerTrust:serverTrust forDomain:nil];
|
||||
}
|
||||
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
|
||||
forDomain:(NSString *)domain
|
||||
{
|
||||
@@ -256,7 +260,6 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
|
||||
switch (self.SSLPinningMode) {
|
||||
case AFSSLPinningModeNone:
|
||||
default:
|
||||
@@ -272,13 +275,16 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSUInteger trustedCertificateCount = 0;
|
||||
for (NSData *trustChainCertificate in serverCertificates) {
|
||||
// obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA)
|
||||
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
|
||||
|
||||
for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
|
||||
if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
|
||||
trustedCertificateCount++;
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return trustedCertificateCount > 0;
|
||||
|
||||
return NO;
|
||||
}
|
||||
case AFSSLPinningModePublicKey: {
|
||||
NSUInteger trustedPublicKeyCount = 0;
|
||||
|
||||
-344
@@ -1,344 +0,0 @@
|
||||
// AFURLConnectionOperation.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import "AFURLRequestSerialization.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
#import "AFSecurityPolicy.h"
|
||||
|
||||
#ifndef NS_DESIGNATED_INITIALIZER
|
||||
#if __has_attribute(objc_designated_initializer)
|
||||
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
#else
|
||||
#define NS_DESIGNATED_INITIALIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
`AFURLConnectionOperation` is a subclass of `NSOperation` that implements `NSURLConnection` delegate methods.
|
||||
|
||||
## Subclassing Notes
|
||||
|
||||
This is the base class of all network request operations. You may wish to create your own subclass in order to implement additional `NSURLConnection` delegate methods (see "`NSURLConnection` Delegate Methods" below), or to provide additional properties and/or class constructors.
|
||||
|
||||
If you are creating a subclass that communicates over the HTTP or HTTPS protocols, you may want to consider subclassing `AFHTTPRequestOperation` instead, as it supports specifying acceptable content types or status codes.
|
||||
|
||||
## NSURLConnection Delegate Methods
|
||||
|
||||
`AFURLConnectionOperation` implements the following `NSURLConnection` delegate methods:
|
||||
|
||||
- `connection:didReceiveResponse:`
|
||||
- `connection:didReceiveData:`
|
||||
- `connectionDidFinishLoading:`
|
||||
- `connection:didFailWithError:`
|
||||
- `connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:`
|
||||
- `connection:willCacheResponse:`
|
||||
- `connectionShouldUseCredentialStorage:`
|
||||
- `connection:needNewBodyStream:`
|
||||
- `connection:willSendRequestForAuthenticationChallenge:`
|
||||
|
||||
If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first.
|
||||
|
||||
## Callbacks and Completion Blocks
|
||||
|
||||
The built-in `completionBlock` provided by `NSOperation` allows for custom behavior to be executed after the request finishes. It is a common pattern for class constructors in subclasses to take callback block parameters, and execute them conditionally in the body of its `completionBlock`. Make sure to handle cancelled operations appropriately when setting a `completionBlock` (i.e. returning early before parsing response data). See the implementation of any of the `AFHTTPRequestOperation` subclasses for an example of this.
|
||||
|
||||
Subclasses are strongly discouraged from overriding `setCompletionBlock:`, as `AFURLConnectionOperation`'s implementation includes a workaround to mitigate retain cycles, and what Apple rather ominously refers to as ["The Deallocation Problem"](http://developer.apple.com/library/ios/#technotes/tn2109/).
|
||||
|
||||
## SSL Pinning
|
||||
|
||||
Relying on the CA trust model to validate SSL certificates exposes your app to security vulnerabilities, such as man-in-the-middle attacks. For applications that connect to known servers, SSL certificate pinning provides an increased level of security, by checking server certificate validity against those specified in the app bundle.
|
||||
|
||||
SSL with certificate pinning is strongly recommended for any application that transmits sensitive information to an external webservice.
|
||||
|
||||
Connections will be validated on all matching certificates with a `.cer` extension in the bundle root.
|
||||
|
||||
## NSCoding & NSCopying Conformance
|
||||
|
||||
`AFURLConnectionOperation` conforms to the `NSCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. However, because of the intrinsic limitations of capturing the exact state of an operation at a particular moment, there are some important caveats to keep in mind:
|
||||
|
||||
### NSCoding Caveats
|
||||
|
||||
- Encoded operations do not include any block or stream properties. Be sure to set `completionBlock`, `outputStream`, and any callback blocks as necessary when using `-initWithCoder:` or `NSKeyedUnarchiver`.
|
||||
- Operations are paused on `encodeWithCoder:`. If the operation was encoded while paused or still executing, its archived state will return `YES` for `isReady`. Otherwise, the state of an operation when encoding will remain unchanged.
|
||||
|
||||
### NSCopying Caveats
|
||||
|
||||
- `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations.
|
||||
- A copy of an operation will not include the `outputStream` of the original.
|
||||
- Operation copies do not include `completionBlock`, as it often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ operation when copied.
|
||||
*/
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AFURLConnectionOperation : NSOperation <NSURLConnectionDelegate, NSURLConnectionDataDelegate, NSSecureCoding, NSCopying>
|
||||
|
||||
///-------------------------------
|
||||
/// @name Accessing Run Loop Modes
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
The run loop modes in which the operation will run on the network thread. By default, this is a single-member set containing `NSRunLoopCommonModes`.
|
||||
*/
|
||||
@property (nonatomic, strong) NSSet *runLoopModes;
|
||||
|
||||
///-----------------------------------------
|
||||
/// @name Getting URL Connection Information
|
||||
///-----------------------------------------
|
||||
|
||||
/**
|
||||
The request used by the operation's connection.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSURLRequest *request;
|
||||
|
||||
/**
|
||||
The last response received by the operation's connection.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong, nullable) NSURLResponse *response;
|
||||
|
||||
/**
|
||||
The error, if any, that occurred in the lifecycle of the request.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong, nullable) NSError *error;
|
||||
|
||||
///----------------------------
|
||||
/// @name Getting Response Data
|
||||
///----------------------------
|
||||
|
||||
/**
|
||||
The data received during the request.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong, nullable) NSData *responseData;
|
||||
|
||||
/**
|
||||
The string representation of the response data.
|
||||
*/
|
||||
@property (readonly, nonatomic, copy, nullable) NSString *responseString;
|
||||
|
||||
/**
|
||||
The string encoding of the response.
|
||||
|
||||
If the response does not specify a valid string encoding, `responseStringEncoding` will return `NSUTF8StringEncoding`.
|
||||
*/
|
||||
@property (readonly, nonatomic, assign) NSStringEncoding responseStringEncoding;
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing URL Credentials
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default.
|
||||
|
||||
This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldUseCredentialStorage;
|
||||
|
||||
/**
|
||||
The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`.
|
||||
|
||||
This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) NSURLCredential *credential;
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing Security Policy
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
The security policy used to evaluate server trust for secure connections.
|
||||
*/
|
||||
@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;
|
||||
|
||||
///------------------------
|
||||
/// @name Accessing Streams
|
||||
///------------------------
|
||||
|
||||
/**
|
||||
The input stream used to read data to be sent during the request.
|
||||
|
||||
This property acts as a proxy to the `HTTPBodyStream` property of `request`.
|
||||
*/
|
||||
@property (nonatomic, strong) NSInputStream *inputStream;
|
||||
|
||||
/**
|
||||
The output stream that is used to write data received until the request is finished.
|
||||
|
||||
By default, data is accumulated into a buffer that is stored into `responseData` upon completion of the request, with the intermediary `outputStream` property set to `nil`. When `outputStream` is set, the data will not be accumulated into an internal buffer, and as a result, the `responseData` property of the completed request will be `nil`. The output stream will be scheduled in the network thread runloop upon being set.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) NSOutputStream *outputStream;
|
||||
|
||||
///---------------------------------
|
||||
/// @name Managing Callback Queues
|
||||
///---------------------------------
|
||||
|
||||
/**
|
||||
The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used.
|
||||
*/
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
@property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;
|
||||
#else
|
||||
@property (nonatomic, assign, nullable) dispatch_queue_t completionQueue;
|
||||
#endif
|
||||
|
||||
/**
|
||||
The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used.
|
||||
*/
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
@property (nonatomic, strong, nullable) dispatch_group_t completionGroup;
|
||||
#else
|
||||
@property (nonatomic, assign, nullable) dispatch_group_t completionGroup;
|
||||
#endif
|
||||
|
||||
///---------------------------------------------
|
||||
/// @name Managing Request Operation Information
|
||||
///---------------------------------------------
|
||||
|
||||
/**
|
||||
The user info dictionary for the receiver.
|
||||
*/
|
||||
@property (nonatomic, strong) NSDictionary *userInfo;
|
||||
// FIXME: It doesn't seem that this userInfo is used anywhere in the implementation.
|
||||
|
||||
///------------------------------------------------------
|
||||
/// @name Initializing an AFURLConnectionOperation Object
|
||||
///------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes and returns a newly allocated operation object with a url connection configured with the specified url request.
|
||||
|
||||
This is the designated initializer.
|
||||
|
||||
@param urlRequest The request object to be used by the operation connection.
|
||||
*/
|
||||
- (instancetype)initWithRequest:(NSURLRequest *)urlRequest NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
///----------------------------------
|
||||
/// @name Pausing / Resuming Requests
|
||||
///----------------------------------
|
||||
|
||||
/**
|
||||
Pauses the execution of the request operation.
|
||||
|
||||
A paused operation returns `NO` for `-isReady`, `-isExecuting`, and `-isFinished`. As such, it will remain in an `NSOperationQueue` until it is either cancelled or resumed. Pausing a finished, cancelled, or paused operation has no effect.
|
||||
*/
|
||||
- (void)pause;
|
||||
|
||||
/**
|
||||
Whether the request operation is currently paused.
|
||||
|
||||
@return `YES` if the operation is currently paused, otherwise `NO`.
|
||||
*/
|
||||
- (BOOL)isPaused;
|
||||
|
||||
/**
|
||||
Resumes the execution of the paused request operation.
|
||||
|
||||
Pause/Resume behavior varies depending on the underlying implementation for the operation class. In its base implementation, resuming a paused requests restarts the original request. However, since HTTP defines a specification for how to request a specific content range, `AFHTTPRequestOperation` will resume downloading the request from where it left off, instead of restarting the original request.
|
||||
*/
|
||||
- (void)resume;
|
||||
|
||||
///----------------------------------------------
|
||||
/// @name Configuring Backgrounding Task Behavior
|
||||
///----------------------------------------------
|
||||
|
||||
/**
|
||||
Specifies that the operation should continue execution after the app has entered the background, and the expiration handler for that background task.
|
||||
|
||||
@param handler A handler to be called shortly before the application’s remaining background time reaches 0. The handler is wrapped in a block that cancels the operation, and cleans up and marks the end of execution, unlike the `handler` parameter in `UIApplication -beginBackgroundTaskWithExpirationHandler:`, which expects this to be done in the handler itself. The handler is called synchronously on the main thread, thus blocking the application’s suspension momentarily while the application is notified.
|
||||
*/
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
- (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(nullable void (^)(void))handler NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
|
||||
#endif
|
||||
|
||||
///---------------------------------
|
||||
/// @name Setting Progress Callbacks
|
||||
///---------------------------------
|
||||
|
||||
/**
|
||||
Sets a callback to be called when an undetermined number of bytes have been uploaded to the server.
|
||||
|
||||
@param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread.
|
||||
*/
|
||||
- (void)setUploadProgressBlock:(nullable void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block;
|
||||
|
||||
/**
|
||||
Sets a callback to be called when an undetermined number of bytes have been downloaded from the server.
|
||||
|
||||
@param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread.
|
||||
*/
|
||||
- (void)setDownloadProgressBlock:(nullable void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block;
|
||||
|
||||
///-------------------------------------------------
|
||||
/// @name Setting NSURLConnection Delegate Callbacks
|
||||
///-------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets a block to be executed when the connection will authenticate a challenge in order to download its request, as handled by the `NSURLConnectionDelegate` method `connection:willSendRequestForAuthenticationChallenge:`.
|
||||
|
||||
@param block A block object to be executed when the connection will authenticate a challenge in order to download its request. The block has no return type and takes two arguments: the URL connection object, and the challenge that must be authenticated. This block must invoke one of the challenge-responder methods (NSURLAuthenticationChallengeSender protocol).
|
||||
|
||||
If `allowsInvalidSSLCertificate` is set to YES, `connection:willSendRequestForAuthenticationChallenge:` will attempt to have the challenge sender use credentials with invalid SSL certificates.
|
||||
*/
|
||||
- (void)setWillSendRequestForAuthenticationChallengeBlock:(nullable void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block;
|
||||
|
||||
/**
|
||||
Sets a block to be executed when the server redirects the request from one URL to another URL, or when the request URL changed by the `NSURLProtocol` subclass handling the request in order to standardize its format, as handled by the `NSURLConnectionDataDelegate` method `connection:willSendRequest:redirectResponse:`.
|
||||
|
||||
@param block A block object to be executed when the request URL was changed. The block returns an `NSURLRequest` object, the URL request to redirect, and takes three arguments: the URL connection object, the the proposed redirected request, and the URL response that caused the redirect.
|
||||
*/
|
||||
- (void)setRedirectResponseBlock:(nullable NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block;
|
||||
|
||||
|
||||
/**
|
||||
Sets a block to be executed to modify the response a connection will cache, if any, as handled by the `NSURLConnectionDelegate` method `connection:willCacheResponse:`.
|
||||
|
||||
@param block A block object to be executed to determine what response a connection will cache, if any. The block returns an `NSCachedURLResponse` object, the cached response to store in memory or `nil` to prevent the response from being cached, and takes two arguments: the URL connection object, and the cached response provided for the request.
|
||||
*/
|
||||
- (void)setCacheResponseBlock:(nullable NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block;
|
||||
|
||||
///
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
+ (NSArray *)batchOfRequestOperations:(nullable NSArray *)operations
|
||||
progressBlock:(nullable void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock
|
||||
completionBlock:(nullable void (^)(NSArray *operations))completionBlock;
|
||||
|
||||
@end
|
||||
|
||||
///--------------------
|
||||
/// @name Notifications
|
||||
///--------------------
|
||||
|
||||
/**
|
||||
Posted when an operation begins executing.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingOperationDidStartNotification;
|
||||
|
||||
/**
|
||||
Posted when an operation finishes.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingOperationDidFinishNotification;
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-792
@@ -1,792 +0,0 @@
|
||||
// AFURLConnectionOperation.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "AFURLConnectionOperation.h"
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error AFNetworking must be built with ARC.
|
||||
// You can turn on ARC for only AFNetworking files by adding -fobjc-arc to the build phase for each of its files.
|
||||
#endif
|
||||
|
||||
typedef NS_ENUM(NSInteger, AFOperationState) {
|
||||
AFOperationPausedState = -1,
|
||||
AFOperationReadyState = 1,
|
||||
AFOperationExecutingState = 2,
|
||||
AFOperationFinishedState = 3,
|
||||
};
|
||||
|
||||
static dispatch_group_t url_request_operation_completion_group() {
|
||||
static dispatch_group_t af_url_request_operation_completion_group;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
af_url_request_operation_completion_group = dispatch_group_create();
|
||||
});
|
||||
|
||||
return af_url_request_operation_completion_group;
|
||||
}
|
||||
|
||||
static dispatch_queue_t url_request_operation_completion_queue() {
|
||||
static dispatch_queue_t af_url_request_operation_completion_queue;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
af_url_request_operation_completion_queue = dispatch_queue_create("com.alamofire.networking.operation.queue", DISPATCH_QUEUE_CONCURRENT );
|
||||
});
|
||||
|
||||
return af_url_request_operation_completion_queue;
|
||||
}
|
||||
|
||||
static NSString * const kAFNetworkingLockName = @"com.alamofire.networking.operation.lock";
|
||||
|
||||
NSString * const AFNetworkingOperationDidStartNotification = @"com.alamofire.networking.operation.start";
|
||||
NSString * const AFNetworkingOperationDidFinishNotification = @"com.alamofire.networking.operation.finish";
|
||||
|
||||
typedef void (^AFURLConnectionOperationProgressBlock)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected);
|
||||
typedef void (^AFURLConnectionOperationAuthenticationChallengeBlock)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge);
|
||||
typedef NSCachedURLResponse * (^AFURLConnectionOperationCacheResponseBlock)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse);
|
||||
typedef NSURLRequest * (^AFURLConnectionOperationRedirectResponseBlock)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse);
|
||||
typedef void (^AFURLConnectionOperationBackgroundTaskCleanupBlock)();
|
||||
|
||||
static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
||||
switch (state) {
|
||||
case AFOperationReadyState:
|
||||
return @"isReady";
|
||||
case AFOperationExecutingState:
|
||||
return @"isExecuting";
|
||||
case AFOperationFinishedState:
|
||||
return @"isFinished";
|
||||
case AFOperationPausedState:
|
||||
return @"isPaused";
|
||||
default: {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
return @"state";
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperationState toState, BOOL isCancelled) {
|
||||
switch (fromState) {
|
||||
case AFOperationReadyState:
|
||||
switch (toState) {
|
||||
case AFOperationPausedState:
|
||||
case AFOperationExecutingState:
|
||||
return YES;
|
||||
case AFOperationFinishedState:
|
||||
return isCancelled;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
case AFOperationExecutingState:
|
||||
switch (toState) {
|
||||
case AFOperationPausedState:
|
||||
case AFOperationFinishedState:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
case AFOperationFinishedState:
|
||||
return NO;
|
||||
case AFOperationPausedState:
|
||||
return toState == AFOperationReadyState;
|
||||
default: {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
switch (toState) {
|
||||
case AFOperationPausedState:
|
||||
case AFOperationReadyState:
|
||||
case AFOperationExecutingState:
|
||||
case AFOperationFinishedState:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
@interface AFURLConnectionOperation ()
|
||||
@property (readwrite, nonatomic, assign) AFOperationState state;
|
||||
@property (readwrite, nonatomic, strong) NSRecursiveLock *lock;
|
||||
@property (readwrite, nonatomic, strong) NSURLConnection *connection;
|
||||
@property (readwrite, nonatomic, strong) NSURLRequest *request;
|
||||
@property (readwrite, nonatomic, strong) NSURLResponse *response;
|
||||
@property (readwrite, nonatomic, strong) NSError *error;
|
||||
@property (readwrite, nonatomic, strong) NSData *responseData;
|
||||
@property (readwrite, nonatomic, copy) NSString *responseString;
|
||||
@property (readwrite, nonatomic, assign) NSStringEncoding responseStringEncoding;
|
||||
@property (readwrite, nonatomic, assign) long long totalBytesRead;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationBackgroundTaskCleanupBlock backgroundTaskCleanup;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock uploadProgress;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock downloadProgress;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationAuthenticationChallengeBlock authenticationChallenge;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationCacheResponseBlock cacheResponse;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationRedirectResponseBlock redirectResponse;
|
||||
|
||||
- (void)operationDidStart;
|
||||
- (void)finish;
|
||||
- (void)cancelConnection;
|
||||
@end
|
||||
|
||||
@implementation AFURLConnectionOperation
|
||||
@synthesize outputStream = _outputStream;
|
||||
|
||||
+ (void)networkRequestThreadEntryPoint:(id)__unused object {
|
||||
@autoreleasepool {
|
||||
[[NSThread currentThread] setName:@"AFNetworking"];
|
||||
|
||||
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
||||
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
|
||||
[runLoop run];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSThread *)networkRequestThread {
|
||||
static NSThread *_networkRequestThread = nil;
|
||||
static dispatch_once_t oncePredicate;
|
||||
dispatch_once(&oncePredicate, ^{
|
||||
_networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];
|
||||
[_networkRequestThread start];
|
||||
});
|
||||
|
||||
return _networkRequestThread;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRequest:(NSURLRequest *)urlRequest {
|
||||
NSParameterAssert(urlRequest);
|
||||
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_state = AFOperationReadyState;
|
||||
|
||||
self.lock = [[NSRecursiveLock alloc] init];
|
||||
self.lock.name = kAFNetworkingLockName;
|
||||
|
||||
self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes];
|
||||
|
||||
self.request = urlRequest;
|
||||
|
||||
self.shouldUseCredentialStorage = YES;
|
||||
|
||||
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
if (_outputStream) {
|
||||
[_outputStream close];
|
||||
_outputStream = nil;
|
||||
}
|
||||
|
||||
if (_backgroundTaskCleanup) {
|
||||
_backgroundTaskCleanup();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setResponseData:(NSData *)responseData {
|
||||
[self.lock lock];
|
||||
if (!responseData) {
|
||||
_responseData = nil;
|
||||
} else {
|
||||
_responseData = [NSData dataWithBytes:responseData.bytes length:responseData.length];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (NSString *)responseString {
|
||||
[self.lock lock];
|
||||
if (!_responseString && self.response && self.responseData) {
|
||||
self.responseString = [[NSString alloc] initWithData:self.responseData encoding:self.responseStringEncoding];
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseString;
|
||||
}
|
||||
|
||||
- (NSStringEncoding)responseStringEncoding {
|
||||
[self.lock lock];
|
||||
if (!_responseStringEncoding && self.response) {
|
||||
NSStringEncoding stringEncoding = NSUTF8StringEncoding;
|
||||
if (self.response.textEncodingName) {
|
||||
CFStringEncoding IANAEncoding = CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)self.response.textEncodingName);
|
||||
if (IANAEncoding != kCFStringEncodingInvalidId) {
|
||||
stringEncoding = CFStringConvertEncodingToNSStringEncoding(IANAEncoding);
|
||||
}
|
||||
}
|
||||
|
||||
self.responseStringEncoding = stringEncoding;
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseStringEncoding;
|
||||
}
|
||||
|
||||
- (NSInputStream *)inputStream {
|
||||
return self.request.HTTPBodyStream;
|
||||
}
|
||||
|
||||
- (void)setInputStream:(NSInputStream *)inputStream {
|
||||
NSMutableURLRequest *mutableRequest = [self.request mutableCopy];
|
||||
mutableRequest.HTTPBodyStream = inputStream;
|
||||
self.request = mutableRequest;
|
||||
}
|
||||
|
||||
- (NSOutputStream *)outputStream {
|
||||
if (!_outputStream) {
|
||||
self.outputStream = [NSOutputStream outputStreamToMemory];
|
||||
}
|
||||
|
||||
return _outputStream;
|
||||
}
|
||||
|
||||
- (void)setOutputStream:(NSOutputStream *)outputStream {
|
||||
[self.lock lock];
|
||||
if (outputStream != _outputStream) {
|
||||
if (_outputStream) {
|
||||
[_outputStream close];
|
||||
}
|
||||
|
||||
_outputStream = outputStream;
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
- (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(void (^)(void))handler {
|
||||
[self.lock lock];
|
||||
if (!self.backgroundTaskCleanup) {
|
||||
UIApplication *application = [UIApplication sharedApplication];
|
||||
UIBackgroundTaskIdentifier __block backgroundTaskIdentifier = UIBackgroundTaskInvalid;
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
|
||||
self.backgroundTaskCleanup = ^(){
|
||||
if (backgroundTaskIdentifier != UIBackgroundTaskInvalid) {
|
||||
[[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier];
|
||||
backgroundTaskIdentifier = UIBackgroundTaskInvalid;
|
||||
}
|
||||
};
|
||||
|
||||
backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
|
||||
if (strongSelf) {
|
||||
[strongSelf cancel];
|
||||
strongSelf.backgroundTaskCleanup();
|
||||
}
|
||||
}];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setState:(AFOperationState)state {
|
||||
if (!AFStateTransitionIsValid(self.state, state, [self isCancelled])) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
NSString *oldStateKey = AFKeyPathFromOperationState(self.state);
|
||||
NSString *newStateKey = AFKeyPathFromOperationState(state);
|
||||
|
||||
[self willChangeValueForKey:newStateKey];
|
||||
[self willChangeValueForKey:oldStateKey];
|
||||
_state = state;
|
||||
[self didChangeValueForKey:oldStateKey];
|
||||
[self didChangeValueForKey:newStateKey];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)pause {
|
||||
if ([self isPaused] || [self isFinished] || [self isCancelled]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
if ([self isExecuting]) {
|
||||
[self performSelector:@selector(operationDidPause) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
[notificationCenter postNotificationName:AFNetworkingOperationDidFinishNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
self.state = AFOperationPausedState;
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)operationDidPause {
|
||||
[self.lock lock];
|
||||
[self.connection cancel];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (BOOL)isPaused {
|
||||
return self.state == AFOperationPausedState;
|
||||
}
|
||||
|
||||
- (void)resume {
|
||||
if (![self isPaused]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
self.state = AFOperationReadyState;
|
||||
|
||||
[self start];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block {
|
||||
self.uploadProgress = block;
|
||||
}
|
||||
|
||||
- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block {
|
||||
self.downloadProgress = block;
|
||||
}
|
||||
|
||||
- (void)setWillSendRequestForAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block {
|
||||
self.authenticationChallenge = block;
|
||||
}
|
||||
|
||||
- (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block {
|
||||
self.cacheResponse = block;
|
||||
}
|
||||
|
||||
- (void)setRedirectResponseBlock:(NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block {
|
||||
self.redirectResponse = block;
|
||||
}
|
||||
|
||||
#pragma mark - NSOperation
|
||||
|
||||
- (void)setCompletionBlock:(void (^)(void))block {
|
||||
[self.lock lock];
|
||||
if (!block) {
|
||||
[super setCompletionBlock:nil];
|
||||
} else {
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
[super setCompletionBlock:^ {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
dispatch_group_t group = strongSelf.completionGroup ?: url_request_operation_completion_group();
|
||||
dispatch_queue_t queue = strongSelf.completionQueue ?: dispatch_get_main_queue();
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
dispatch_group_async(group, queue, ^{
|
||||
block();
|
||||
});
|
||||
|
||||
dispatch_group_notify(group, url_request_operation_completion_queue(), ^{
|
||||
[strongSelf setCompletionBlock:nil];
|
||||
});
|
||||
}];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (BOOL)isReady {
|
||||
return self.state == AFOperationReadyState && [super isReady];
|
||||
}
|
||||
|
||||
- (BOOL)isExecuting {
|
||||
return self.state == AFOperationExecutingState;
|
||||
}
|
||||
|
||||
- (BOOL)isFinished {
|
||||
return self.state == AFOperationFinishedState;
|
||||
}
|
||||
|
||||
- (BOOL)isConcurrent {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)start {
|
||||
[self.lock lock];
|
||||
if ([self isCancelled]) {
|
||||
[self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
|
||||
} else if ([self isReady]) {
|
||||
self.state = AFOperationExecutingState;
|
||||
|
||||
[self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)operationDidStart {
|
||||
[self.lock lock];
|
||||
if (![self isCancelled]) {
|
||||
self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];
|
||||
|
||||
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
||||
for (NSString *runLoopMode in self.runLoopModes) {
|
||||
[self.connection scheduleInRunLoop:runLoop forMode:runLoopMode];
|
||||
[self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode];
|
||||
}
|
||||
|
||||
[self.outputStream open];
|
||||
[self.connection start];
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidStartNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)finish {
|
||||
[self.lock lock];
|
||||
self.state = AFOperationFinishedState;
|
||||
[self.lock unlock];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[self.lock lock];
|
||||
if (![self isFinished] && ![self isCancelled]) {
|
||||
[super cancel];
|
||||
|
||||
if ([self isExecuting]) {
|
||||
[self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
|
||||
}
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)cancelConnection {
|
||||
NSDictionary *userInfo = nil;
|
||||
if ([self.request URL]) {
|
||||
userInfo = @{NSURLErrorFailingURLErrorKey : [self.request URL]};
|
||||
}
|
||||
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo];
|
||||
|
||||
if (![self isFinished]) {
|
||||
if (self.connection) {
|
||||
[self.connection cancel];
|
||||
[self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:error];
|
||||
} else {
|
||||
// Accommodate race condition where `self.connection` has not yet been set before cancellation
|
||||
self.error = error;
|
||||
[self finish];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (NSArray *)batchOfRequestOperations:(NSArray *)operations
|
||||
progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock
|
||||
completionBlock:(void (^)(NSArray *operations))completionBlock
|
||||
{
|
||||
if (!operations || [operations count] == 0) {
|
||||
return @[[NSBlockOperation blockOperationWithBlock:^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (completionBlock) {
|
||||
completionBlock(@[]);
|
||||
}
|
||||
});
|
||||
}]];
|
||||
}
|
||||
|
||||
__block dispatch_group_t group = dispatch_group_create();
|
||||
NSBlockOperation *batchedOperation = [NSBlockOperation blockOperationWithBlock:^{
|
||||
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
|
||||
if (completionBlock) {
|
||||
completionBlock(operations);
|
||||
}
|
||||
});
|
||||
}];
|
||||
|
||||
for (AFURLConnectionOperation *operation in operations) {
|
||||
operation.completionGroup = group;
|
||||
void (^originalCompletionBlock)(void) = [operation.completionBlock copy];
|
||||
__weak __typeof(operation)weakOperation = operation;
|
||||
operation.completionBlock = ^{
|
||||
__strong __typeof(weakOperation)strongOperation = weakOperation;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
dispatch_queue_t queue = strongOperation.completionQueue ?: dispatch_get_main_queue();
|
||||
#pragma clang diagnostic pop
|
||||
dispatch_group_async(group, queue, ^{
|
||||
if (originalCompletionBlock) {
|
||||
originalCompletionBlock();
|
||||
}
|
||||
|
||||
NSUInteger numberOfFinishedOperations = [[operations indexesOfObjectsPassingTest:^BOOL(id op, NSUInteger __unused idx, BOOL __unused *stop) {
|
||||
return [op isFinished];
|
||||
}] count];
|
||||
|
||||
if (progressBlock) {
|
||||
progressBlock(numberOfFinishedOperations, [operations count]);
|
||||
}
|
||||
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
};
|
||||
|
||||
dispatch_group_enter(group);
|
||||
[batchedOperation addDependency:operation];
|
||||
}
|
||||
|
||||
return [operations arrayByAddingObject:batchedOperation];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
[self.lock lock];
|
||||
NSString *description = [NSString stringWithFormat:@"<%@: %p, state: %@, cancelled: %@ request: %@, response: %@>", NSStringFromClass([self class]), self, AFKeyPathFromOperationState(self.state), ([self isCancelled] ? @"YES" : @"NO"), self.request, self.response];
|
||||
[self.lock unlock];
|
||||
return description;
|
||||
}
|
||||
|
||||
#pragma mark - NSURLConnectionDelegate
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection
|
||||
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
|
||||
{
|
||||
if (self.authenticationChallenge) {
|
||||
self.authenticationChallenge(connection, challenge);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
||||
if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
|
||||
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
|
||||
} else {
|
||||
[[challenge sender] cancelAuthenticationChallenge:challenge];
|
||||
}
|
||||
} else {
|
||||
if ([challenge previousFailureCount] == 0) {
|
||||
if (self.credential) {
|
||||
[[challenge sender] useCredential:self.credential forAuthenticationChallenge:challenge];
|
||||
} else {
|
||||
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
|
||||
}
|
||||
} else {
|
||||
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connection {
|
||||
return self.shouldUseCredentialStorage;
|
||||
}
|
||||
|
||||
- (NSURLRequest *)connection:(NSURLConnection *)connection
|
||||
willSendRequest:(NSURLRequest *)request
|
||||
redirectResponse:(NSURLResponse *)redirectResponse
|
||||
{
|
||||
if (self.redirectResponse) {
|
||||
return self.redirectResponse(connection, request, redirectResponse);
|
||||
} else {
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection __unused *)connection
|
||||
didSendBodyData:(NSInteger)bytesWritten
|
||||
totalBytesWritten:(NSInteger)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.uploadProgress) {
|
||||
self.uploadProgress((NSUInteger)bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection __unused *)connection
|
||||
didReceiveResponse:(NSURLResponse *)response
|
||||
{
|
||||
self.response = response;
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection __unused *)connection
|
||||
didReceiveData:(NSData *)data
|
||||
{
|
||||
NSUInteger length = [data length];
|
||||
while (YES) {
|
||||
NSInteger totalNumberOfBytesWritten = 0;
|
||||
if ([self.outputStream hasSpaceAvailable]) {
|
||||
const uint8_t *dataBuffer = (uint8_t *)[data bytes];
|
||||
|
||||
NSInteger numberOfBytesWritten = 0;
|
||||
while (totalNumberOfBytesWritten < (NSInteger)length) {
|
||||
numberOfBytesWritten = [self.outputStream write:&dataBuffer[(NSUInteger)totalNumberOfBytesWritten] maxLength:(length - (NSUInteger)totalNumberOfBytesWritten)];
|
||||
if (numberOfBytesWritten == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
totalNumberOfBytesWritten += numberOfBytesWritten;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
[self.connection cancel];
|
||||
if (self.outputStream.streamError) {
|
||||
[self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:self.outputStream.streamError];
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.totalBytesRead += (long long)length;
|
||||
|
||||
if (self.downloadProgress) {
|
||||
self.downloadProgress(length, self.totalBytesRead, self.response.expectedContentLength);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection __unused *)connection {
|
||||
self.responseData = [self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
|
||||
|
||||
[self.outputStream close];
|
||||
if (self.responseData) {
|
||||
self.outputStream = nil;
|
||||
}
|
||||
|
||||
self.connection = nil;
|
||||
|
||||
[self finish];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection __unused *)connection
|
||||
didFailWithError:(NSError *)error
|
||||
{
|
||||
self.error = error;
|
||||
|
||||
[self.outputStream close];
|
||||
if (self.responseData) {
|
||||
self.outputStream = nil;
|
||||
}
|
||||
|
||||
self.connection = nil;
|
||||
|
||||
[self finish];
|
||||
}
|
||||
|
||||
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
|
||||
willCacheResponse:(NSCachedURLResponse *)cachedResponse
|
||||
{
|
||||
if (self.cacheResponse) {
|
||||
return self.cacheResponse(connection, cachedResponse);
|
||||
} else {
|
||||
if ([self isCancelled]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return cachedResponse;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
NSURLRequest *request = [decoder decodeObjectOfClass:[NSURLRequest class] forKey:NSStringFromSelector(@selector(request))];
|
||||
|
||||
self = [self initWithRequest:request];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.state = (AFOperationState)[[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(state))] integerValue];
|
||||
self.response = [decoder decodeObjectOfClass:[NSHTTPURLResponse class] forKey:NSStringFromSelector(@selector(response))];
|
||||
self.error = [decoder decodeObjectOfClass:[NSError class] forKey:NSStringFromSelector(@selector(error))];
|
||||
self.responseData = [decoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(responseData))];
|
||||
self.totalBytesRead = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(totalBytesRead))] longLongValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||
[self pause];
|
||||
|
||||
[coder encodeObject:self.request forKey:NSStringFromSelector(@selector(request))];
|
||||
|
||||
switch (self.state) {
|
||||
case AFOperationExecutingState:
|
||||
case AFOperationPausedState:
|
||||
[coder encodeInteger:AFOperationReadyState forKey:NSStringFromSelector(@selector(state))];
|
||||
break;
|
||||
default:
|
||||
[coder encodeInteger:self.state forKey:NSStringFromSelector(@selector(state))];
|
||||
break;
|
||||
}
|
||||
|
||||
[coder encodeObject:self.response forKey:NSStringFromSelector(@selector(response))];
|
||||
[coder encodeObject:self.error forKey:NSStringFromSelector(@selector(error))];
|
||||
[coder encodeObject:self.responseData forKey:NSStringFromSelector(@selector(responseData))];
|
||||
[coder encodeInt64:self.totalBytesRead forKey:NSStringFromSelector(@selector(totalBytesRead))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
AFURLConnectionOperation *operation = [(AFURLConnectionOperation *)[[self class] allocWithZone:zone] initWithRequest:self.request];
|
||||
|
||||
operation.uploadProgress = self.uploadProgress;
|
||||
operation.downloadProgress = self.downloadProgress;
|
||||
operation.authenticationChallenge = self.authenticationChallenge;
|
||||
operation.cacheResponse = self.cacheResponse;
|
||||
operation.redirectResponse = self.redirectResponse;
|
||||
operation.completionQueue = self.completionQueue;
|
||||
operation.completionGroup = self.completionGroup;
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
@end
|
||||
Regular → Executable
+40
-37
@@ -1,5 +1,5 @@
|
||||
// AFURLRequestSerialization.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,9 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#if TARGET_OS_IOS
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
#import <UIKit/UIKit.h>
|
||||
#elif TARGET_OS_WATCH
|
||||
#import <WatchKit/WatchKit.h>
|
||||
@@ -28,6 +30,31 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Returns a percent-escaped string following RFC 3986 for a query string key or value.
|
||||
RFC 3986 states that the following characters are "reserved" characters.
|
||||
- General Delimiters: ":", "#", "[", "]", "@", "?", "/"
|
||||
- Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
|
||||
|
||||
In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
|
||||
query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
|
||||
should be percent-escaped in the query string.
|
||||
|
||||
@param string The string to be percent-escaped.
|
||||
|
||||
@return The percent-escaped string.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * AFPercentEscapedStringFromString(NSString *string);
|
||||
|
||||
/**
|
||||
A helper method to generate encoded url query parameters for appending to the end of a URL.
|
||||
|
||||
@param parameters A dictionary of key/values to be encoded.
|
||||
|
||||
@return A url encoded query string
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * AFQueryStringFromParameters(NSDictionary *parameters);
|
||||
|
||||
/**
|
||||
The `AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary.
|
||||
|
||||
@@ -46,11 +73,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
|
||||
withParameters:(nullable id)parameters
|
||||
error:(NSError * __nullable __autoreleasing *)error
|
||||
#ifdef NS_SWIFT_NOTHROW
|
||||
NS_SWIFT_NOTHROW
|
||||
#endif
|
||||
;
|
||||
error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@@ -130,7 +154,7 @@ typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) {
|
||||
|
||||
@discussion To add or remove default request headers, use `setValue:forHTTPHeaderField:`.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSDictionary *HTTPRequestHeaders;
|
||||
@property (readonly, nonatomic, strong) NSDictionary <NSString *, NSString *> *HTTPRequestHeaders;
|
||||
|
||||
/**
|
||||
Creates and returns a serializer with default configuration.
|
||||
@@ -164,12 +188,6 @@ forHTTPHeaderField:(NSString *)field;
|
||||
- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username
|
||||
password:(NSString *)password;
|
||||
|
||||
/**
|
||||
@deprecated This method has been deprecated. Use -setValue:forHTTPHeaderField: instead.
|
||||
*/
|
||||
- (void)setAuthorizationHeaderFieldWithToken:(NSString *)token DEPRECATED_ATTRIBUTE;
|
||||
|
||||
|
||||
/**
|
||||
Clears any existing value for the "Authorization" HTTP header.
|
||||
*/
|
||||
@@ -182,7 +200,7 @@ forHTTPHeaderField:(NSString *)field;
|
||||
/**
|
||||
HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default.
|
||||
*/
|
||||
@property (nonatomic, strong) NSSet *HTTPMethodsEncodingParametersInURI;
|
||||
@property (nonatomic, strong) NSSet <NSString *> *HTTPMethodsEncodingParametersInURI;
|
||||
|
||||
/**
|
||||
Set the method of query string serialization according to one of the pre-defined styles.
|
||||
@@ -204,13 +222,6 @@ forHTTPHeaderField:(NSString *)field;
|
||||
/// @name Creating Request Objects
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
@deprecated This method has been deprecated. Use -requestWithMethod:URLString:parameters:error: instead.
|
||||
*/
|
||||
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(id)parameters DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string.
|
||||
|
||||
@@ -226,15 +237,7 @@ forHTTPHeaderField:(NSString *)field;
|
||||
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(nullable id)parameters
|
||||
error:(NSError * __nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
@deprecated This method has been deprecated. Use -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error: instead.
|
||||
*/
|
||||
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block DEPRECATED_ATTRIBUTE;
|
||||
error:(NSError * _Nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
|
||||
@@ -251,9 +254,9 @@ forHTTPHeaderField:(NSString *)field;
|
||||
*/
|
||||
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(nullable NSDictionary *)parameters
|
||||
parameters:(nullable NSDictionary <NSString *, id> *)parameters
|
||||
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
|
||||
error:(NSError * __nullable __autoreleasing *)error;
|
||||
error:(NSError * _Nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
Creates an `NSMutableURLRequest` by removing the `HTTPBodyStream` from a request, and asynchronously writing its contents into the specified file, invoking the completion handler when finished.
|
||||
@@ -268,7 +271,7 @@ forHTTPHeaderField:(NSString *)field;
|
||||
*/
|
||||
- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request
|
||||
writingStreamContentsToFile:(NSURL *)fileURL
|
||||
completionHandler:(nullable void (^)(NSError * __nullable error))handler;
|
||||
completionHandler:(nullable void (^)(NSError * _Nullable error))handler;
|
||||
|
||||
@end
|
||||
|
||||
@@ -292,7 +295,7 @@ forHTTPHeaderField:(NSString *)field;
|
||||
*/
|
||||
- (BOOL)appendPartWithFileURL:(NSURL *)fileURL
|
||||
name:(NSString *)name
|
||||
error:(NSError * __nullable __autoreleasing *)error;
|
||||
error:(NSError * _Nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary.
|
||||
@@ -309,7 +312,7 @@ forHTTPHeaderField:(NSString *)field;
|
||||
name:(NSString *)name
|
||||
fileName:(NSString *)fileName
|
||||
mimeType:(NSString *)mimeType
|
||||
error:(NSError * __nullable __autoreleasing *)error;
|
||||
error:(NSError * _Nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary.
|
||||
@@ -356,7 +359,7 @@ forHTTPHeaderField:(NSString *)field;
|
||||
@param headers The HTTP headers to be appended to the form data.
|
||||
@param body The data to be encoded and appended to the form data. This parameter must not be `nil`.
|
||||
*/
|
||||
- (void)appendPartWithHeaders:(nullable NSDictionary *)headers
|
||||
- (void)appendPartWithHeaders:(nullable NSDictionary <NSString *, NSString *> *)headers
|
||||
body:(NSData *)body;
|
||||
|
||||
/**
|
||||
|
||||
Regular → Executable
+24
-76
@@ -1,5 +1,5 @@
|
||||
// AFURLRequestSerialization.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#import "AFURLRequestSerialization.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
#if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
#else
|
||||
#import <CoreServices/CoreServices.h>
|
||||
@@ -32,35 +32,6 @@ NSString * const AFNetworkingOperationFailingURLRequestErrorKey = @"com.alamofir
|
||||
|
||||
typedef NSString * (^AFQueryStringSerializationBlock)(NSURLRequest *request, id parameters, NSError *__autoreleasing *error);
|
||||
|
||||
static NSString * AFBase64EncodedStringFromString(NSString *string) {
|
||||
NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
|
||||
NSUInteger length = [data length];
|
||||
NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
|
||||
|
||||
uint8_t *input = (uint8_t *)[data bytes];
|
||||
uint8_t *output = (uint8_t *)[mutableData mutableBytes];
|
||||
|
||||
for (NSUInteger i = 0; i < length; i += 3) {
|
||||
NSUInteger value = 0;
|
||||
for (NSUInteger j = i; j < (i + 3); j++) {
|
||||
value <<= 8;
|
||||
if (j < length) {
|
||||
value |= (0xFF & input[j]);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
NSUInteger idx = (i / 3) * 4;
|
||||
output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F];
|
||||
output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F];
|
||||
output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6) & 0x3F] : '=';
|
||||
output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0) & 0x3F] : '=';
|
||||
}
|
||||
|
||||
return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding];
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a percent-escaped string following RFC 3986 for a query string key or value.
|
||||
RFC 3986 states that the following characters are "reserved" characters.
|
||||
@@ -73,7 +44,7 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) {
|
||||
- parameter string: The string to be percent-escaped.
|
||||
- returns: The percent-escaped string.
|
||||
*/
|
||||
static NSString * AFPercentEscapedStringFromString(NSString *string) {
|
||||
NSString * AFPercentEscapedStringFromString(NSString *string) {
|
||||
static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
|
||||
static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
|
||||
|
||||
@@ -114,14 +85,14 @@ static NSString * AFPercentEscapedStringFromString(NSString *string) {
|
||||
@property (readwrite, nonatomic, strong) id field;
|
||||
@property (readwrite, nonatomic, strong) id value;
|
||||
|
||||
- (id)initWithField:(id)field value:(id)value;
|
||||
- (instancetype)initWithField:(id)field value:(id)value;
|
||||
|
||||
- (NSString *)URLEncodedStringValue;
|
||||
@end
|
||||
|
||||
@implementation AFQueryStringPair
|
||||
|
||||
- (id)initWithField:(id)field value:(id)value {
|
||||
- (instancetype)initWithField:(id)field value:(id)value {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -148,7 +119,7 @@ static NSString * AFPercentEscapedStringFromString(NSString *string) {
|
||||
FOUNDATION_EXPORT NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary);
|
||||
FOUNDATION_EXPORT NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value);
|
||||
|
||||
static NSString * AFQueryStringFromParameters(NSDictionary *parameters) {
|
||||
NSString * AFQueryStringFromParameters(NSDictionary *parameters) {
|
||||
NSMutableArray *mutablePairs = [NSMutableArray array];
|
||||
for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) {
|
||||
[mutablePairs addObject:[pair URLEncodedStringValue]];
|
||||
@@ -351,12 +322,9 @@ forHTTPHeaderField:(NSString *)field
|
||||
- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username
|
||||
password:(NSString *)password
|
||||
{
|
||||
NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", username, password];
|
||||
[self setValue:[NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)] forHTTPHeaderField:@"Authorization"];
|
||||
}
|
||||
|
||||
- (void)setAuthorizationHeaderFieldWithToken:(NSString *)token {
|
||||
[self setValue:[NSString stringWithFormat:@"Token token=\"%@\"", token] forHTTPHeaderField:@"Authorization"];
|
||||
NSData *basicAuthCredentials = [[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSString *base64AuthCredentials = [basicAuthCredentials base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0];
|
||||
[self setValue:[NSString stringWithFormat:@"Basic %@", base64AuthCredentials] forHTTPHeaderField:@"Authorization"];
|
||||
}
|
||||
|
||||
- (void)clearAuthorizationHeader {
|
||||
@@ -376,13 +344,6 @@ forHTTPHeaderField:(NSString *)field
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
{
|
||||
return [self requestWithMethod:method URLString:URLString parameters:parameters error:nil];
|
||||
}
|
||||
|
||||
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
@@ -409,14 +370,6 @@ forHTTPHeaderField:(NSString *)field
|
||||
return mutableRequest;
|
||||
}
|
||||
|
||||
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
|
||||
{
|
||||
return [self multipartFormRequestWithMethod:method URLString:URLString parameters:parameters constructingBodyWithBlock:block error:nil];
|
||||
}
|
||||
|
||||
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
@@ -547,7 +500,7 @@ forHTTPHeaderField:(NSString *)field
|
||||
}
|
||||
|
||||
if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
|
||||
if (query) {
|
||||
if (query && query.length > 0) {
|
||||
mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];
|
||||
}
|
||||
} else {
|
||||
@@ -594,7 +547,7 @@ forHTTPHeaderField:(NSString *)field
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [self init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -613,7 +566,7 @@ forHTTPHeaderField:(NSString *)field
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFHTTPRequestSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
serializer.mutableHTTPRequestHeaders = [self.mutableHTTPRequestHeaders mutableCopyWithZone:zone];
|
||||
serializer.queryStringSerializationStyle = self.queryStringSerializationStyle;
|
||||
@@ -645,7 +598,6 @@ static inline NSString * AFMultipartFormFinalBoundary(NSString *boundary) {
|
||||
}
|
||||
|
||||
static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||
#ifdef __UTTYPE__
|
||||
NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
|
||||
NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
|
||||
if (!contentType) {
|
||||
@@ -653,10 +605,6 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||
} else {
|
||||
return contentType;
|
||||
}
|
||||
#else
|
||||
#pragma unused (extension)
|
||||
return @"application/octet-stream";
|
||||
#endif
|
||||
}
|
||||
|
||||
NSUInteger const kAFUploadStream3GSuggestedPacketSize = 1024 * 16;
|
||||
@@ -687,7 +635,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
@property (readonly, nonatomic, assign) unsigned long long contentLength;
|
||||
@property (readonly, nonatomic, assign, getter = isEmpty) BOOL empty;
|
||||
|
||||
- (id)initWithStringEncoding:(NSStringEncoding)encoding;
|
||||
- (instancetype)initWithStringEncoding:(NSStringEncoding)encoding;
|
||||
- (void)setInitialAndFinalBoundaries;
|
||||
- (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart;
|
||||
@end
|
||||
@@ -703,8 +651,8 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
|
||||
@implementation AFStreamingMultipartFormData
|
||||
|
||||
- (id)initWithURLRequest:(NSMutableURLRequest *)urlRequest
|
||||
stringEncoding:(NSStringEncoding)encoding
|
||||
- (instancetype)initWithURLRequest:(NSMutableURLRequest *)urlRequest
|
||||
stringEncoding:(NSStringEncoding)encoding
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
@@ -896,7 +844,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
@synthesize streamError;
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
- (id)initWithStringEncoding:(NSStringEncoding)encoding {
|
||||
- (instancetype)initWithStringEncoding:(NSStringEncoding)encoding {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -948,7 +896,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
NSUInteger maxLength = length - (NSUInteger)totalNumberOfBytesRead;
|
||||
NSUInteger maxLength = MIN(length, self.numberOfBytesInPacket) - (NSUInteger)totalNumberOfBytesRead;
|
||||
NSInteger numberOfBytesRead = [self.currentHTTPBodyPart read:&buffer[totalNumberOfBytesRead] maxLength:maxLength];
|
||||
if (numberOfBytesRead == -1) {
|
||||
self.streamError = self.currentHTTPBodyPart.inputStream.streamError;
|
||||
@@ -1039,7 +987,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
-(id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFMultipartBodyStream *bodyStreamCopy = [[[self class] allocWithZone:zone] initWithStringEncoding:self.stringEncoding];
|
||||
|
||||
for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) {
|
||||
@@ -1076,7 +1024,7 @@ typedef enum {
|
||||
|
||||
@implementation AFHTTPBodyPart
|
||||
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -1254,7 +1202,7 @@ typedef enum {
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFHTTPBodyPart *bodyPart = [[[self class] allocWithZone:zone] init];
|
||||
|
||||
bodyPart.stringEncoding = self.stringEncoding;
|
||||
@@ -1317,7 +1265,7 @@ typedef enum {
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -1336,7 +1284,7 @@ typedef enum {
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFJSONRequestSerializer *serializer = [super copyWithZone:zone];
|
||||
serializer.writingOptions = self.writingOptions;
|
||||
|
||||
@@ -1396,7 +1344,7 @@ typedef enum {
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -1417,7 +1365,7 @@ typedef enum {
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFPropertyListRequestSerializer *serializer = [super copyWithZone:zone];
|
||||
serializer.format = self.format;
|
||||
serializer.writeOptions = self.writeOptions;
|
||||
|
||||
Regular → Executable
+7
-11
@@ -1,5 +1,5 @@
|
||||
// AFURLResponseSerialization.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -42,11 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response
|
||||
data:(nullable NSData *)data
|
||||
error:(NSError * __nullable __autoreleasing *)error
|
||||
#ifdef NS_SWIFT_NOTHROW
|
||||
NS_SWIFT_NOTHROW
|
||||
#endif
|
||||
;
|
||||
error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW;
|
||||
|
||||
@end
|
||||
|
||||
@@ -85,7 +81,7 @@ NS_SWIFT_NOTHROW
|
||||
/**
|
||||
The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation.
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSSet *acceptableContentTypes;
|
||||
@property (nonatomic, copy, nullable) NSSet <NSString *> *acceptableContentTypes;
|
||||
|
||||
/**
|
||||
Validates the specified response and data.
|
||||
@@ -100,7 +96,7 @@ NS_SWIFT_NOTHROW
|
||||
*/
|
||||
- (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response
|
||||
data:(nullable NSData *)data
|
||||
error:(NSError * __nullable __autoreleasing *)error;
|
||||
error:(NSError * _Nullable __autoreleasing *)error;
|
||||
|
||||
@end
|
||||
|
||||
@@ -239,7 +235,7 @@ NS_SWIFT_NOTHROW
|
||||
*/
|
||||
@interface AFImageResponseSerializer : AFHTTPResponseSerializer
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
|
||||
/**
|
||||
The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance.
|
||||
*/
|
||||
@@ -263,14 +259,14 @@ NS_SWIFT_NOTHROW
|
||||
/**
|
||||
The component response serializers.
|
||||
*/
|
||||
@property (readonly, nonatomic, copy) NSArray *responseSerializers;
|
||||
@property (readonly, nonatomic, copy) NSArray <id<AFURLResponseSerialization>> *responseSerializers;
|
||||
|
||||
/**
|
||||
Creates and returns a compound serializer comprised of the specified response serializers.
|
||||
|
||||
@warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`.
|
||||
*/
|
||||
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers;
|
||||
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray <id<AFURLResponseSerialization>> *)responseSerializers;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
Regular → Executable
+34
-54
@@ -1,5 +1,5 @@
|
||||
// AFURLResponseSerialization.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#import "AFURLResponseSerialization.h"
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <UIKit/UIKit.h>
|
||||
#elif TARGET_OS_WATCH
|
||||
@@ -113,7 +115,9 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
NSError *validationError = nil;
|
||||
|
||||
if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]]) {
|
||||
if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]] &&
|
||||
!([response MIMEType] == nil && [data length] == 0)) {
|
||||
|
||||
if ([data length] > 0 && [response URL]) {
|
||||
NSMutableDictionary *mutableUserInfo = [@{
|
||||
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]],
|
||||
@@ -171,7 +175,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [self init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -190,7 +194,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFHTTPResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
serializer.acceptableStatusCodes = [self.acceptableStatusCodes copyWithZone:zone];
|
||||
serializer.acceptableContentTypes = [self.acceptableContentTypes copyWithZone:zone];
|
||||
@@ -238,40 +242,15 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization.
|
||||
// See https://github.com/rails/rails/issues/1742
|
||||
NSStringEncoding stringEncoding = self.stringEncoding;
|
||||
if (response.textEncodingName) {
|
||||
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName);
|
||||
if (encoding != kCFStringEncodingInvalidId) {
|
||||
stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);
|
||||
}
|
||||
}
|
||||
|
||||
id responseObject = nil;
|
||||
NSError *serializationError = nil;
|
||||
@autoreleasepool {
|
||||
NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding];
|
||||
if (responseString && ![responseString isEqualToString:@" "]) {
|
||||
// Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character
|
||||
// See http://stackoverflow.com/a/12843465/157142
|
||||
data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
if (data) {
|
||||
if ([data length] > 0) {
|
||||
responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
} else {
|
||||
NSDictionary *userInfo = @{
|
||||
NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", @"AFNetworking", nil),
|
||||
NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking", nil), responseString]
|
||||
};
|
||||
|
||||
serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
|
||||
}
|
||||
}
|
||||
// Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization.
|
||||
// See https://github.com/rails/rails/issues/1742
|
||||
BOOL isSpace = [data isEqualToData:[NSData dataWithBytes:" " length:1]];
|
||||
if (data.length > 0 && !isSpace) {
|
||||
responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (self.removesKeysWithNullValues && responseObject) {
|
||||
@@ -287,7 +266,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -308,7 +287,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFJSONResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
serializer.readingOptions = self.readingOptions;
|
||||
serializer.removesKeysWithNullValues = self.removesKeysWithNullValues;
|
||||
@@ -408,7 +387,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -427,7 +406,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFXMLDocumentResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
serializer.options = self.options;
|
||||
|
||||
@@ -495,7 +474,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -516,7 +495,7 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFPropertyListResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
serializer.format = self.format;
|
||||
serializer.readOptions = self.readOptions;
|
||||
@@ -528,8 +507,9 @@ static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingO
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIImage (AFNetworkingSafeImageLoading)
|
||||
+ (UIImage *)af_safeImageWithData:(NSData *)data;
|
||||
@@ -667,10 +647,10 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
|
||||
self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil];
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
self.imageScale = [[UIScreen mainScreen] scale];
|
||||
self.automaticallyInflatesResponseImage = YES;
|
||||
#elif TARGET_OS_WATCH
|
||||
#elif TARGET_OS_WATCH
|
||||
self.imageScale = [[WKInterfaceDevice currentDevice] screenScale];
|
||||
self.automaticallyInflatesResponseImage = YES;
|
||||
#endif
|
||||
@@ -690,13 +670,13 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
|
||||
if (self.automaticallyInflatesResponseImage) {
|
||||
return AFInflatedImageFromResponseWithDataAtScale((NSHTTPURLResponse *)response, data, self.imageScale);
|
||||
} else {
|
||||
return AFImageWithDataAtScale(data, self.imageScale);
|
||||
}
|
||||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
#else
|
||||
// Ensure that the image is set to it's correct pixel width and height
|
||||
NSBitmapImageRep *bitimage = [[NSBitmapImageRep alloc] initWithData:data];
|
||||
NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize([bitimage pixelsWide], [bitimage pixelsHigh])];
|
||||
@@ -710,13 +690,13 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
|
||||
NSNumber *imageScale = [decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(imageScale))];
|
||||
#if CGFLOAT_IS_DOUBLE
|
||||
self.imageScale = [imageScale doubleValue];
|
||||
@@ -733,7 +713,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||
[super encodeWithCoder:coder];
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
|
||||
[coder encodeObject:@(self.imageScale) forKey:NSStringFromSelector(@selector(imageScale))];
|
||||
[coder encodeBool:self.automaticallyInflatesResponseImage forKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))];
|
||||
#endif
|
||||
@@ -741,10 +721,10 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFImageResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
|
||||
serializer.imageScale = self.imageScale;
|
||||
serializer.automaticallyInflatesResponseImage = self.automaticallyInflatesResponseImage;
|
||||
#endif
|
||||
@@ -796,7 +776,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
@@ -815,7 +795,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
AFCompoundResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
serializer.responseSerializers = self.responseSerializers;
|
||||
|
||||
|
||||
Regular → Executable
+50
-104
@@ -1,5 +1,5 @@
|
||||
// AFURLSessionManager.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -19,6 +19,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "AFURLResponseSerialization.h"
|
||||
@@ -28,14 +29,6 @@
|
||||
#import "AFNetworkReachabilityManager.h"
|
||||
#endif
|
||||
|
||||
#ifndef NS_DESIGNATED_INITIALIZER
|
||||
#if __has_attribute(objc_designated_initializer)
|
||||
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
#else
|
||||
#define NS_DESIGNATED_INITIALIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
`AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to `<NSURLSessionTaskDelegate>`, `<NSURLSessionDataDelegate>`, `<NSURLSessionDownloadDelegate>`, and `<NSURLSessionDelegate>`.
|
||||
|
||||
@@ -58,6 +51,7 @@
|
||||
- `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:`
|
||||
- `URLSession:task:didReceiveChallenge:completionHandler:`
|
||||
- `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`
|
||||
- `URLSession:task:needNewBodyStream:`
|
||||
- `URLSession:task:didCompleteWithError:`
|
||||
|
||||
### `NSURLSessionDataDelegate`
|
||||
@@ -93,8 +87,6 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || TARGET_OS_WATCH
|
||||
|
||||
@interface AFURLSessionManager : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate, NSSecureCoding, NSCopying>
|
||||
|
||||
/**
|
||||
@@ -119,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
The security policy used by created request operations to evaluate server trust for secure connections. `AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified.
|
||||
The security policy used by created session to evaluate server trust for secure connections. `AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified.
|
||||
*/
|
||||
@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;
|
||||
|
||||
@@ -141,22 +133,22 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
The data, upload, and download tasks currently run by the managed session.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSArray *tasks;
|
||||
@property (readonly, nonatomic, strong) NSArray <NSURLSessionTask *> *tasks;
|
||||
|
||||
/**
|
||||
The data tasks currently run by the managed session.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSArray *dataTasks;
|
||||
@property (readonly, nonatomic, strong) NSArray <NSURLSessionDataTask *> *dataTasks;
|
||||
|
||||
/**
|
||||
The upload tasks currently run by the managed session.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSArray *uploadTasks;
|
||||
@property (readonly, nonatomic, strong) NSArray <NSURLSessionUploadTask *> *uploadTasks;
|
||||
|
||||
/**
|
||||
The download tasks currently run by the managed session.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSArray *downloadTasks;
|
||||
@property (readonly, nonatomic, strong) NSArray <NSURLSessionDownloadTask *> *downloadTasks;
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing Callback Queues
|
||||
@@ -165,20 +157,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used.
|
||||
*/
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
@property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;
|
||||
#else
|
||||
@property (nonatomic, assign, nullable) dispatch_queue_t completionQueue;
|
||||
#endif
|
||||
|
||||
/**
|
||||
The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used.
|
||||
*/
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
@property (nonatomic, strong, nullable) dispatch_group_t completionGroup;
|
||||
#else
|
||||
@property (nonatomic, assign, nullable) dispatch_group_t completionGroup;
|
||||
#endif
|
||||
|
||||
///---------------------------------
|
||||
/// @name Working Around System Bugs
|
||||
@@ -224,7 +208,20 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any.
|
||||
*/
|
||||
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id __nullable responseObject, NSError * __nullable error))completionHandler;
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
Creates an `NSURLSessionDataTask` with the specified request.
|
||||
|
||||
@param request The HTTP request for the request.
|
||||
@param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any.
|
||||
*/
|
||||
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
|
||||
uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
|
||||
downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
|
||||
|
||||
///---------------------------
|
||||
/// @name Running Upload Tasks
|
||||
@@ -235,39 +232,39 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@param request The HTTP request for the request.
|
||||
@param fileURL A URL to the local file to be uploaded.
|
||||
@param progress A progress object monitoring the current upload progress.
|
||||
@param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any.
|
||||
|
||||
@see `attemptsToRecreateUploadTasksForBackgroundSessions`
|
||||
*/
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
|
||||
fromFile:(NSURL *)fileURL
|
||||
progress:(NSProgress * __nullable __autoreleasing * __nullable)progress
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id __nullable responseObject, NSError * __nullable error))completionHandler;
|
||||
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
Creates an `NSURLSessionUploadTask` with the specified request for an HTTP body.
|
||||
|
||||
@param request The HTTP request for the request.
|
||||
@param bodyData A data object containing the HTTP body to be uploaded.
|
||||
@param progress A progress object monitoring the current upload progress.
|
||||
@param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any.
|
||||
*/
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
|
||||
fromData:(nullable NSData *)bodyData
|
||||
progress:(NSProgress * __nullable __autoreleasing * __nullable)progress
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id __nullable responseObject, NSError * __nullable error))completionHandler;
|
||||
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
Creates an `NSURLSessionUploadTask` with the specified streaming request.
|
||||
|
||||
@param request The HTTP request for the request.
|
||||
@param progress A progress object monitoring the current upload progress.
|
||||
@param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any.
|
||||
*/
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request
|
||||
progress:(NSProgress * __nullable __autoreleasing * __nullable)progress
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id __nullable responseObject, NSError * __nullable error))completionHandler;
|
||||
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Running Download Tasks
|
||||
@@ -277,29 +274,29 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
Creates an `NSURLSessionDownloadTask` with the specified request.
|
||||
|
||||
@param request The HTTP request for the request.
|
||||
@param progress A progress object monitoring the current download progress.
|
||||
@param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL.
|
||||
@param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any.
|
||||
|
||||
@warning If using a background `NSURLSessionConfiguration` on iOS, these blocks will be lost when the app is terminated. Background sessions may prefer to use `-setDownloadTaskDidFinishDownloadingBlock:` to specify the URL for saving the downloaded file, rather than the destination block of this method.
|
||||
*/
|
||||
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
|
||||
progress:(NSProgress * __nullable __autoreleasing * __nullable)progress
|
||||
progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
|
||||
destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * __nullable filePath, NSError * __nullable error))completionHandler;
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
Creates an `NSURLSessionDownloadTask` with the specified resume data.
|
||||
|
||||
@param resumeData The data used to resume downloading.
|
||||
@param progress A progress object monitoring the current download progress.
|
||||
@param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue.
|
||||
@param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL.
|
||||
@param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any.
|
||||
*/
|
||||
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
|
||||
progress:(NSProgress * __nullable __autoreleasing * __nullable)progress
|
||||
progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
|
||||
destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * __nullable filePath, NSError * __nullable error))completionHandler;
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;
|
||||
|
||||
///---------------------------------
|
||||
/// @name Getting Progress for Tasks
|
||||
@@ -308,20 +305,20 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
Returns the upload progress of the specified task.
|
||||
|
||||
@param uploadTask The session upload task. Must not be `nil`.
|
||||
@param task The session task. Must not be `nil`.
|
||||
|
||||
@return An `NSProgress` object reporting the upload progress of a task, or `nil` if the progress is unavailable.
|
||||
*/
|
||||
- (nullable NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask;
|
||||
- (nullable NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task;
|
||||
|
||||
/**
|
||||
Returns the download progress of the specified task.
|
||||
|
||||
@param downloadTask The session download task. Must not be `nil`.
|
||||
@param task The session task. Must not be `nil`.
|
||||
|
||||
@return An `NSProgress` object reporting the download progress of a task, or `nil` if the progress is unavailable.
|
||||
*/
|
||||
- (nullable NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask;
|
||||
- (nullable NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task;
|
||||
|
||||
///-----------------------------------------
|
||||
/// @name Setting Session Delegate Callbacks
|
||||
@@ -339,7 +336,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@param block A block object to be executed when a connection level authentication challenge has occurred. The block returns the disposition of the authentication challenge, and takes three arguments: the session, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge.
|
||||
*/
|
||||
- (void)setSessionDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __nullable __autoreleasing * __nullable credential))block;
|
||||
- (void)setSessionDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential))block;
|
||||
|
||||
///--------------------------------------
|
||||
/// @name Setting Task Delegate Callbacks
|
||||
@@ -364,7 +361,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@param block A block object to be executed when a session task has received a request specific authentication challenge. The block returns the disposition of the authentication challenge, and takes four arguments: the session, the task, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge.
|
||||
*/
|
||||
- (void)setTaskDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __nullable __autoreleasing * __nullable credential))block;
|
||||
- (void)setTaskDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential))block;
|
||||
|
||||
/**
|
||||
Sets a block to be executed periodically to track upload progress, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`.
|
||||
@@ -378,7 +375,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@param block A block object to be executed when a session task is completed. The block has no return value, and takes three arguments: the session, the task, and any error that occurred in the process of executing the task.
|
||||
*/
|
||||
- (void)setTaskDidCompleteBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, NSError * __nullable error))block;
|
||||
- (void)setTaskDidCompleteBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, NSError * _Nullable error))block;
|
||||
|
||||
///-------------------------------------------
|
||||
/// @name Setting Data Task Delegate Callbacks
|
||||
@@ -428,7 +425,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@param block A block object to be executed when a download task has completed. The block returns the URL the download should be moved to, and takes three arguments: the session, the download task, and the temporary location of the downloaded file. If the file manager encounters an error while attempting to move the temporary file to the destination, an `AFURLSessionDownloadTaskDidFailToMoveFileNotification` will be posted, with the download task as its object, and the user info of the error.
|
||||
*/
|
||||
- (void)setDownloadTaskDidFinishDownloadingBlock:(nullable NSURL * __nullable (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block;
|
||||
- (void)setDownloadTaskDidFinishDownloadingBlock:(nullable NSURL * _Nullable (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block;
|
||||
|
||||
/**
|
||||
Sets a block to be executed periodically to track download progress, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:`.
|
||||
@@ -446,31 +443,15 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
///--------------------
|
||||
/// @name Notifications
|
||||
///--------------------
|
||||
|
||||
/**
|
||||
Posted when a task begins executing.
|
||||
|
||||
@deprecated Use `AFNetworkingTaskDidResumeNotification` instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidStartNotification DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
Posted when a task resumes.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidResumeNotification;
|
||||
|
||||
/**
|
||||
Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task.
|
||||
|
||||
@deprecated Use `AFNetworkingTaskDidCompleteNotification` instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidFinishNotification DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task.
|
||||
*/
|
||||
@@ -492,62 +473,27 @@ FOUNDATION_EXPORT NSString * const AFURLSessionDidInvalidateNotification;
|
||||
FOUNDATION_EXPORT NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification;
|
||||
|
||||
/**
|
||||
The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if response data exists for the task.
|
||||
|
||||
@deprecated Use `AFNetworkingTaskDidCompleteResponseDataKey` instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidFinishResponseDataKey DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if response data exists for the task.
|
||||
The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if response data exists for the task.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteResponseDataKey;
|
||||
|
||||
/**
|
||||
The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the response was serialized.
|
||||
|
||||
@deprecated Use `AFNetworkingTaskDidCompleteSerializedResponseKey` instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidFinishSerializedResponseKey DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the response was serialized.
|
||||
The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if the response was serialized.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey;
|
||||
|
||||
/**
|
||||
The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the task has an associated response serializer.
|
||||
|
||||
@deprecated Use `AFNetworkingTaskDidCompleteResponseSerializerKey` instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidFinishResponseSerializerKey DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the task has an associated response serializer.
|
||||
The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if the task has an associated response serializer.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey;
|
||||
|
||||
/**
|
||||
The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an the response data has been stored directly to disk.
|
||||
|
||||
@deprecated Use `AFNetworkingTaskDidCompleteAssetPathKey` instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidFinishAssetPathKey DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an the response data has been stored directly to disk.
|
||||
The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if an the response data has been stored directly to disk.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteAssetPathKey;
|
||||
|
||||
/**
|
||||
Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an error exists.
|
||||
|
||||
@deprecated Use `AFNetworkingTaskDidCompleteErrorKey` instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidFinishErrorKey DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an error exists.
|
||||
Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if an error exists.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteErrorKey;
|
||||
|
||||
|
||||
Regular → Executable
+189
-119
@@ -1,5 +1,5 @@
|
||||
// AFURLSessionManager.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,11 @@
|
||||
#import "AFURLSessionManager.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
|
||||
#ifndef NSFoundationVersionNumber_iOS_8_0
|
||||
#define NSFoundationVersionNumber_With_Fixed_5871104061079552_bug 1140.11
|
||||
#else
|
||||
#define NSFoundationVersionNumber_With_Fixed_5871104061079552_bug NSFoundationVersionNumber_iOS_8_0
|
||||
#endif
|
||||
|
||||
static dispatch_queue_t url_session_manager_creation_queue() {
|
||||
static dispatch_queue_t af_url_session_manager_creation_queue;
|
||||
@@ -34,6 +38,17 @@ static dispatch_queue_t url_session_manager_creation_queue() {
|
||||
return af_url_session_manager_creation_queue;
|
||||
}
|
||||
|
||||
static void url_session_manager_create_task_safely(dispatch_block_t block) {
|
||||
if (NSFoundationVersionNumber < NSFoundationVersionNumber_With_Fixed_5871104061079552_bug) {
|
||||
// Fix of bug
|
||||
// Open Radar:http://openradar.appspot.com/radar?id=5871104061079552 (status: Fixed in iOS8)
|
||||
// Issue about:https://github.com/AFNetworking/AFNetworking/issues/2093
|
||||
dispatch_sync(url_session_manager_creation_queue(), block);
|
||||
} else {
|
||||
block();
|
||||
}
|
||||
}
|
||||
|
||||
static dispatch_queue_t url_session_manager_processing_queue() {
|
||||
static dispatch_queue_t af_url_session_manager_processing_queue;
|
||||
static dispatch_once_t onceToken;
|
||||
@@ -60,21 +75,12 @@ NSString * const AFNetworkingTaskDidSuspendNotification = @"com.alamofire.networ
|
||||
NSString * const AFURLSessionDidInvalidateNotification = @"com.alamofire.networking.session.invalidate";
|
||||
NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification = @"com.alamofire.networking.session.download.file-manager-error";
|
||||
|
||||
NSString * const AFNetworkingTaskDidStartNotification = @"com.alamofire.networking.task.resume"; // Deprecated
|
||||
NSString * const AFNetworkingTaskDidFinishNotification = @"com.alamofire.networking.task.complete"; // Deprecated
|
||||
|
||||
NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse";
|
||||
NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer";
|
||||
NSString * const AFNetworkingTaskDidCompleteResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata";
|
||||
NSString * const AFNetworkingTaskDidCompleteErrorKey = @"com.alamofire.networking.task.complete.error";
|
||||
NSString * const AFNetworkingTaskDidCompleteAssetPathKey = @"com.alamofire.networking.task.complete.assetpath";
|
||||
|
||||
NSString * const AFNetworkingTaskDidFinishSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse"; // Deprecated
|
||||
NSString * const AFNetworkingTaskDidFinishResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer"; // Deprecated
|
||||
NSString * const AFNetworkingTaskDidFinishResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata"; // Deprecated
|
||||
NSString * const AFNetworkingTaskDidFinishErrorKey = @"com.alamofire.networking.task.complete.error"; // Deprecated
|
||||
NSString * const AFNetworkingTaskDidFinishAssetPathKey = @"com.alamofire.networking.task.complete.assetpath"; // Deprecated
|
||||
|
||||
static NSString * const AFURLSessionManagerLockName = @"com.alamofire.networking.session.manager.lock";
|
||||
|
||||
static NSUInteger const AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask = 3;
|
||||
@@ -100,17 +106,22 @@ typedef NSCachedURLResponse * (^AFURLSessionDataTaskWillCacheResponseBlock)(NSUR
|
||||
typedef NSURL * (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location);
|
||||
typedef void (^AFURLSessionDownloadTaskDidWriteDataBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite);
|
||||
typedef void (^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes);
|
||||
typedef void (^AFURLSessionTaskProgressBlock)(NSProgress *);
|
||||
|
||||
typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id responseObject, NSError *error);
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
|
||||
@property (nonatomic, weak) AFURLSessionManager *manager;
|
||||
@property (nonatomic, strong) NSMutableData *mutableData;
|
||||
@property (nonatomic, strong) NSProgress *progress;
|
||||
@property (nonatomic, strong) NSProgress *uploadProgress;
|
||||
@property (nonatomic, strong) NSProgress *downloadProgress;
|
||||
@property (nonatomic, copy) NSURL *downloadFileURL;
|
||||
@property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading;
|
||||
@property (nonatomic, copy) AFURLSessionTaskProgressBlock uploadProgressBlock;
|
||||
@property (nonatomic, copy) AFURLSessionTaskProgressBlock downloadProgressBlock;
|
||||
@property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler;
|
||||
@end
|
||||
|
||||
@@ -123,24 +134,119 @@ typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id re
|
||||
}
|
||||
|
||||
self.mutableData = [NSMutableData data];
|
||||
self.uploadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
|
||||
self.uploadProgress.totalUnitCount = NSURLSessionTransferSizeUnknown;
|
||||
|
||||
self.progress = [NSProgress progressWithTotalUnitCount:0];
|
||||
|
||||
self.downloadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
|
||||
self.downloadProgress.totalUnitCount = NSURLSessionTransferSizeUnknown;
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSURLSessionTaskDelegate
|
||||
#pragma mark - NSProgress Tracking
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
task:(__unused NSURLSessionTask *)task
|
||||
didSendBodyData:(__unused int64_t)bytesSent
|
||||
totalBytesSent:(int64_t)totalBytesSent
|
||||
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
|
||||
{
|
||||
self.progress.totalUnitCount = totalBytesExpectedToSend;
|
||||
self.progress.completedUnitCount = totalBytesSent;
|
||||
- (void)setupProgressForTask:(NSURLSessionTask *)task {
|
||||
__weak __typeof__(task) weakTask = task;
|
||||
|
||||
self.uploadProgress.totalUnitCount = task.countOfBytesExpectedToSend;
|
||||
self.downloadProgress.totalUnitCount = task.countOfBytesExpectedToReceive;
|
||||
[self.uploadProgress setCancellable:YES];
|
||||
[self.uploadProgress setCancellationHandler:^{
|
||||
__typeof__(weakTask) strongTask = weakTask;
|
||||
[strongTask cancel];
|
||||
}];
|
||||
[self.uploadProgress setPausable:YES];
|
||||
[self.uploadProgress setPausingHandler:^{
|
||||
__typeof__(weakTask) strongTask = weakTask;
|
||||
[strongTask suspend];
|
||||
}];
|
||||
if ([self.uploadProgress respondsToSelector:@selector(setResumingHandler:)]) {
|
||||
[self.uploadProgress setResumingHandler:^{
|
||||
__typeof__(weakTask) strongTask = weakTask;
|
||||
[strongTask resume];
|
||||
}];
|
||||
}
|
||||
|
||||
[self.downloadProgress setCancellable:YES];
|
||||
[self.downloadProgress setCancellationHandler:^{
|
||||
__typeof__(weakTask) strongTask = weakTask;
|
||||
[strongTask cancel];
|
||||
}];
|
||||
[self.downloadProgress setPausable:YES];
|
||||
[self.downloadProgress setPausingHandler:^{
|
||||
__typeof__(weakTask) strongTask = weakTask;
|
||||
[strongTask suspend];
|
||||
}];
|
||||
|
||||
if ([self.downloadProgress respondsToSelector:@selector(setResumingHandler:)]) {
|
||||
[self.downloadProgress setResumingHandler:^{
|
||||
__typeof__(weakTask) strongTask = weakTask;
|
||||
[strongTask resume];
|
||||
}];
|
||||
}
|
||||
|
||||
[task addObserver:self
|
||||
forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived))
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
[task addObserver:self
|
||||
forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToReceive))
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
|
||||
[task addObserver:self
|
||||
forKeyPath:NSStringFromSelector(@selector(countOfBytesSent))
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
[task addObserver:self
|
||||
forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToSend))
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
|
||||
[self.downloadProgress addObserver:self
|
||||
forKeyPath:NSStringFromSelector(@selector(fractionCompleted))
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
[self.uploadProgress addObserver:self
|
||||
forKeyPath:NSStringFromSelector(@selector(fractionCompleted))
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
}
|
||||
|
||||
- (void)cleanUpProgressForTask:(NSURLSessionTask *)task {
|
||||
[task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived))];
|
||||
[task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToReceive))];
|
||||
[task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesSent))];
|
||||
[task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToSend))];
|
||||
[self.downloadProgress removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted))];
|
||||
[self.uploadProgress removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted))];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
|
||||
if ([object isKindOfClass:[NSURLSessionTask class]] || [object isKindOfClass:[NSURLSessionDownloadTask class]]) {
|
||||
if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesReceived))]) {
|
||||
self.downloadProgress.completedUnitCount = [change[NSKeyValueChangeNewKey] longLongValue];
|
||||
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesExpectedToReceive))]) {
|
||||
self.downloadProgress.totalUnitCount = [change[NSKeyValueChangeNewKey] longLongValue];
|
||||
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) {
|
||||
self.uploadProgress.completedUnitCount = [change[NSKeyValueChangeNewKey] longLongValue];
|
||||
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesExpectedToSend))]) {
|
||||
self.uploadProgress.totalUnitCount = [change[NSKeyValueChangeNewKey] longLongValue];
|
||||
}
|
||||
}
|
||||
else if ([object isEqual:self.downloadProgress]) {
|
||||
if (self.downloadProgressBlock) {
|
||||
self.downloadProgressBlock(object);
|
||||
}
|
||||
}
|
||||
else if ([object isEqual:self.uploadProgress]) {
|
||||
if (self.uploadProgressBlock) {
|
||||
self.uploadProgressBlock(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - NSURLSessionTaskDelegate
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
task:(NSURLSessionTask *)task
|
||||
didCompleteWithError:(NSError *)error
|
||||
@@ -241,24 +347,6 @@ didFinishDownloadingToURL:(NSURL *)location
|
||||
}
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
downloadTask:(__unused NSURLSessionDownloadTask *)downloadTask
|
||||
didWriteData:(__unused int64_t)bytesWritten
|
||||
totalBytesWritten:(int64_t)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
{
|
||||
self.progress.totalUnitCount = totalBytesExpectedToWrite;
|
||||
self.progress.completedUnitCount = totalBytesWritten;
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
downloadTask:(__unused NSURLSessionDownloadTask *)downloadTask
|
||||
didResumeAtOffset:(int64_t)fileOffset
|
||||
expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
self.progress.totalUnitCount = expectedTotalBytes;
|
||||
self.progress.completedUnitCount = fileOffset;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@@ -452,7 +540,7 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
|
||||
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
|
||||
for (NSURLSessionDataTask *task in dataTasks) {
|
||||
[self addDelegateForDataTask:task completionHandler:nil];
|
||||
[self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
|
||||
}
|
||||
|
||||
for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
|
||||
@@ -464,9 +552,6 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
}
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:nil];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -523,10 +608,14 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
|
||||
[self.lock lock];
|
||||
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
|
||||
[delegate setupProgressForTask:task];
|
||||
[self addNotificationObserverForTask:task];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask
|
||||
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
|
||||
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
|
||||
@@ -535,48 +624,28 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
|
||||
dataTask.taskDescription = self.taskDescriptionForSessionTasks;
|
||||
[self setDelegate:delegate forTask:dataTask];
|
||||
|
||||
delegate.uploadProgressBlock = uploadProgressBlock;
|
||||
delegate.downloadProgressBlock = downloadProgressBlock;
|
||||
}
|
||||
|
||||
- (void)addDelegateForUploadTask:(NSURLSessionUploadTask *)uploadTask
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
|
||||
delegate.manager = self;
|
||||
delegate.completionHandler = completionHandler;
|
||||
|
||||
int64_t totalUnitCount = uploadTask.countOfBytesExpectedToSend;
|
||||
if(totalUnitCount == NSURLSessionTransferSizeUnknown) {
|
||||
NSString *contentLength = [uploadTask.originalRequest valueForHTTPHeaderField:@"Content-Length"];
|
||||
if(contentLength) {
|
||||
totalUnitCount = (int64_t)[contentLength longLongValue];
|
||||
}
|
||||
}
|
||||
|
||||
if (delegate.progress) {
|
||||
delegate.progress.totalUnitCount = totalUnitCount;
|
||||
} else {
|
||||
delegate.progress = [NSProgress progressWithTotalUnitCount:totalUnitCount];
|
||||
}
|
||||
|
||||
delegate.progress.pausingHandler = ^{
|
||||
[uploadTask suspend];
|
||||
};
|
||||
delegate.progress.cancellationHandler = ^{
|
||||
[uploadTask cancel];
|
||||
};
|
||||
|
||||
if (progress) {
|
||||
*progress = delegate.progress;
|
||||
}
|
||||
|
||||
uploadTask.taskDescription = self.taskDescriptionForSessionTasks;
|
||||
|
||||
[self setDelegate:delegate forTask:uploadTask];
|
||||
|
||||
delegate.uploadProgressBlock = uploadProgressBlock;
|
||||
}
|
||||
|
||||
- (void)addDelegateForDownloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
|
||||
{
|
||||
@@ -590,29 +659,24 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
};
|
||||
}
|
||||
|
||||
if (progress) {
|
||||
*progress = delegate.progress;
|
||||
}
|
||||
|
||||
downloadTask.taskDescription = self.taskDescriptionForSessionTasks;
|
||||
|
||||
[self setDelegate:delegate forTask:downloadTask];
|
||||
|
||||
delegate.downloadProgressBlock = downloadProgressBlock;
|
||||
}
|
||||
|
||||
- (void)removeDelegateForTask:(NSURLSessionTask *)task {
|
||||
NSParameterAssert(task);
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
|
||||
[self.lock lock];
|
||||
[delegate cleanUpProgressForTask:task];
|
||||
[self removeNotificationObserverForTask:task];
|
||||
[self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)removeAllDelegates {
|
||||
[self.lock lock];
|
||||
[self.mutableTaskDelegatesKeyedByTaskIdentifier removeAllObjects];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSArray *)tasksForKeyPath:(NSString *)keyPath {
|
||||
@@ -673,17 +737,36 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
_responseSerializer = responseSerializer;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (void)addNotificationObserverForTask:(NSURLSessionTask *)task {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:task];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:task];
|
||||
}
|
||||
|
||||
- (void)removeNotificationObserverForTask:(NSURLSessionTask *)task {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AFNSURLSessionTaskDidSuspendNotification object:task];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AFNSURLSessionTaskDidResumeNotification object:task];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
return [self dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
|
||||
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
|
||||
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
|
||||
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler {
|
||||
|
||||
__block NSURLSessionDataTask *dataTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
url_session_manager_create_task_safely(^{
|
||||
dataTask = [self.session dataTaskWithRequest:request];
|
||||
});
|
||||
|
||||
[self addDelegateForDataTask:dataTask completionHandler:completionHandler];
|
||||
[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
|
||||
|
||||
return dataTask;
|
||||
}
|
||||
@@ -692,11 +775,11 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
|
||||
fromFile:(NSURL *)fileURL
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
__block NSURLSessionUploadTask *uploadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
url_session_manager_create_task_safely(^{
|
||||
uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL];
|
||||
});
|
||||
|
||||
@@ -706,36 +789,36 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
}
|
||||
}
|
||||
|
||||
[self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
[self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler];
|
||||
|
||||
return uploadTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
|
||||
fromData:(NSData *)bodyData
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
__block NSURLSessionUploadTask *uploadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
url_session_manager_create_task_safely(^{
|
||||
uploadTask = [self.session uploadTaskWithRequest:request fromData:bodyData];
|
||||
});
|
||||
|
||||
[self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
[self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler];
|
||||
|
||||
return uploadTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
__block NSURLSessionUploadTask *uploadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
url_session_manager_create_task_safely(^{
|
||||
uploadTask = [self.session uploadTaskWithStreamedRequest:request];
|
||||
});
|
||||
|
||||
[self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
[self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler];
|
||||
|
||||
return uploadTask;
|
||||
}
|
||||
@@ -743,43 +826,42 @@ static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofi
|
||||
#pragma mark -
|
||||
|
||||
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
|
||||
{
|
||||
__block NSURLSessionDownloadTask *downloadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
url_session_manager_create_task_safely(^{
|
||||
downloadTask = [self.session downloadTaskWithRequest:request];
|
||||
});
|
||||
|
||||
[self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler];
|
||||
[self addDelegateForDownloadTask:downloadTask progress:downloadProgressBlock destination:destination completionHandler:completionHandler];
|
||||
|
||||
return downloadTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
|
||||
{
|
||||
__block NSURLSessionDownloadTask *downloadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
url_session_manager_create_task_safely(^{
|
||||
downloadTask = [self.session downloadTaskWithResumeData:resumeData];
|
||||
});
|
||||
|
||||
[self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler];
|
||||
[self addDelegateForDownloadTask:downloadTask progress:downloadProgressBlock destination:destination completionHandler:completionHandler];
|
||||
|
||||
return downloadTask;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask {
|
||||
return [[self delegateForTask:uploadTask] progress];
|
||||
- (NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task {
|
||||
return [[self delegateForTask:task] uploadProgress];
|
||||
}
|
||||
|
||||
- (NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask {
|
||||
return [[self delegateForTask:downloadTask] progress];
|
||||
- (NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task {
|
||||
return [[self delegateForTask:task] downloadProgress];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -879,7 +961,6 @@ didBecomeInvalidWithError:(NSError *)error
|
||||
self.sessionDidBecomeInvalid(session, error);
|
||||
}
|
||||
|
||||
[self removeAllDelegates];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDidInvalidateNotification object:session];
|
||||
}
|
||||
|
||||
@@ -993,9 +1074,6 @@ totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
|
||||
}
|
||||
}
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
|
||||
[delegate URLSession:session task:task didSendBodyData:bytesSent totalBytesSent:totalBytesSent totalBytesExpectedToSend:totalUnitCount];
|
||||
|
||||
if (self.taskDidSendBodyData) {
|
||||
self.taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalUnitCount);
|
||||
}
|
||||
@@ -1017,7 +1095,6 @@ didCompleteWithError:(NSError *)error
|
||||
if (self.taskDidComplete) {
|
||||
self.taskDidComplete(session, task, error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - NSURLSessionDataDelegate
|
||||
@@ -1057,6 +1134,7 @@ didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
dataTask:(NSURLSessionDataTask *)dataTask
|
||||
didReceiveData:(NSData *)data
|
||||
{
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask];
|
||||
[delegate URLSession:session dataTask:dataTask didReceiveData:data];
|
||||
|
||||
@@ -1121,9 +1199,6 @@ didFinishDownloadingToURL:(NSURL *)location
|
||||
totalBytesWritten:(int64_t)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask];
|
||||
[delegate URLSession:session downloadTask:downloadTask didWriteData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite];
|
||||
|
||||
if (self.downloadTaskDidWriteData) {
|
||||
self.downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
|
||||
}
|
||||
@@ -1134,9 +1209,6 @@ totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
didResumeAtOffset:(int64_t)fileOffset
|
||||
expectedTotalBytes:(int64_t)expectedTotalBytes
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask];
|
||||
[delegate URLSession:session downloadTask:downloadTask didResumeAtOffset:fileOffset expectedTotalBytes:expectedTotalBytes];
|
||||
|
||||
if (self.downloadTaskDidResume) {
|
||||
self.downloadTaskDidResume(session, downloadTask, fileOffset, expectedTotalBytes);
|
||||
}
|
||||
@@ -1148,7 +1220,7 @@ expectedTotalBytes:(int64_t)expectedTotalBytes
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"];
|
||||
|
||||
self = [self initWithSessionConfiguration:configuration];
|
||||
@@ -1165,10 +1237,8 @@ expectedTotalBytes:(int64_t)expectedTotalBytes
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
return [[[self class] allocWithZone:zone] initWithSessionConfiguration:self.session.configuration];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+149
@@ -0,0 +1,149 @@
|
||||
// AFAutoPurgingImageCache.h
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
The `AFImageCache` protocol defines a set of APIs for adding, removing and fetching images from a cache synchronously.
|
||||
*/
|
||||
@protocol AFImageCache <NSObject>
|
||||
|
||||
/**
|
||||
Adds the image to the cache with the given identifier.
|
||||
|
||||
@param image The image to cache.
|
||||
@param identifier The unique identifier for the image in the cache.
|
||||
*/
|
||||
- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier;
|
||||
|
||||
/**
|
||||
Removes the image from the cache matching the given identifier.
|
||||
|
||||
@param identifier The unique identifier for the image in the cache.
|
||||
|
||||
@return A BOOL indicating whether or not the image was removed from the cache.
|
||||
*/
|
||||
- (BOOL)removeImageWithIdentifier:(NSString *)identifier;
|
||||
|
||||
/**
|
||||
Removes all images from the cache.
|
||||
|
||||
@return A BOOL indicating whether or not all images were removed from the cache.
|
||||
*/
|
||||
- (BOOL)removeAllImages;
|
||||
|
||||
/**
|
||||
Returns the image in the cache associated with the given identifier.
|
||||
|
||||
@param identifier The unique identifier for the image in the cache.
|
||||
|
||||
@return An image for the matching identifier, or nil.
|
||||
*/
|
||||
- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier;
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
The `ImageRequestCache` protocol extends the `ImageCache` protocol by adding methods for adding, removing and fetching images from a cache given an `NSURLRequest` and additional identifier.
|
||||
*/
|
||||
@protocol AFImageRequestCache <AFImageCache>
|
||||
|
||||
/**
|
||||
Adds the image to the cache using an identifier created from the request and additional identifier.
|
||||
|
||||
@param image The image to cache.
|
||||
@param request The unique URL request identifing the image asset.
|
||||
@param identifier The additional identifier to apply to the URL request to identify the image.
|
||||
*/
|
||||
- (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
|
||||
|
||||
/**
|
||||
Removes the image from the cache using an identifier created from the request and additional identifier.
|
||||
|
||||
@param request The unique URL request identifing the image asset.
|
||||
@param identifier The additional identifier to apply to the URL request to identify the image.
|
||||
|
||||
@return A BOOL indicating whether or not all images were removed from the cache.
|
||||
*/
|
||||
- (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
|
||||
|
||||
/**
|
||||
Returns the image from the cache associated with an identifier created from the request and additional identifier.
|
||||
|
||||
@param request The unique URL request identifing the image asset.
|
||||
@param identifier The additional identifier to apply to the URL request to identify the image.
|
||||
|
||||
@return An image for the matching request and identifier, or nil.
|
||||
*/
|
||||
- (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
The `AutoPurgingImageCache` in an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated.
|
||||
*/
|
||||
@interface AFAutoPurgingImageCache : NSObject <AFImageRequestCache>
|
||||
|
||||
/**
|
||||
The total memory capacity of the cache in bytes.
|
||||
*/
|
||||
@property (nonatomic, assign) UInt64 memoryCapacity;
|
||||
|
||||
/**
|
||||
The preferred memory usage after purge in bytes. During a purge, images will be purged until the memory capacity drops below this limit.
|
||||
*/
|
||||
@property (nonatomic, assign) UInt64 preferredMemoryUsageAfterPurge;
|
||||
|
||||
/**
|
||||
The current total memory usage in bytes of all images stored within the cache.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) UInt64 memoryUsage;
|
||||
|
||||
/**
|
||||
Initialies the `AutoPurgingImageCache` instance with default values for memory capacity and preferred memory usage after purge limit. `memoryCapcity` defaults to `100 MB`. `preferredMemoryUsageAfterPurge` defaults to `60 MB`.
|
||||
|
||||
@return The new `AutoPurgingImageCache` instance.
|
||||
*/
|
||||
- (instancetype)init;
|
||||
|
||||
/**
|
||||
Initialies the `AutoPurgingImageCache` instance with the given memory capacity and preferred memory usage
|
||||
after purge limit.
|
||||
|
||||
@param memoryCapacity The total memory capacity of the cache in bytes.
|
||||
@param preferredMemoryCapacity The preferred memory usage after purge in bytes.
|
||||
|
||||
@return The new `AutoPurgingImageCache` instance.
|
||||
*/
|
||||
- (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+201
@@ -0,0 +1,201 @@
|
||||
// AFAutoPurgingImageCache.m
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import "AFAutoPurgingImageCache.h"
|
||||
|
||||
@interface AFCachedImage : NSObject
|
||||
|
||||
@property (nonatomic, strong) UIImage *image;
|
||||
@property (nonatomic, strong) NSString *identifier;
|
||||
@property (nonatomic, assign) UInt64 totalBytes;
|
||||
@property (nonatomic, strong) NSDate *lastAccessDate;
|
||||
@property (nonatomic, assign) UInt64 currentMemoryUsage;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AFCachedImage
|
||||
|
||||
-(instancetype)initWithImage:(UIImage *)image identifier:(NSString *)identifier {
|
||||
if (self = [self init]) {
|
||||
self.image = image;
|
||||
self.identifier = identifier;
|
||||
|
||||
CGSize imageSize = CGSizeMake(image.size.width * image.scale, image.size.height * image.scale);
|
||||
CGFloat bytesPerPixel = 4.0;
|
||||
CGFloat bytesPerSize = imageSize.width * imageSize.height;
|
||||
self.totalBytes = (UInt64)bytesPerPixel * (UInt64)bytesPerSize;
|
||||
self.lastAccessDate = [NSDate date];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIImage*)accessImage {
|
||||
self.lastAccessDate = [NSDate date];
|
||||
return self.image;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
NSString *descriptionString = [NSString stringWithFormat:@"Idenfitier: %@ lastAccessDate: %@ ", self.identifier, self.lastAccessDate];
|
||||
return descriptionString;
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface AFAutoPurgingImageCache ()
|
||||
@property (nonatomic, strong) NSMutableDictionary <NSString* , AFCachedImage*> *cachedImages;
|
||||
@property (nonatomic, assign) UInt64 currentMemoryUsage;
|
||||
@property (nonatomic, strong) dispatch_queue_t synchronizationQueue;
|
||||
@end
|
||||
|
||||
@implementation AFAutoPurgingImageCache
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithMemoryCapacity:100 * 1024 * 1024 preferredMemoryCapacity:60 * 1024 * 1024];
|
||||
}
|
||||
|
||||
- (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity {
|
||||
if (self = [super init]) {
|
||||
self.memoryCapacity = memoryCapacity;
|
||||
self.preferredMemoryUsageAfterPurge = preferredMemoryCapacity;
|
||||
self.cachedImages = [[NSMutableDictionary alloc] init];
|
||||
|
||||
NSString *queueName = [NSString stringWithFormat:@"com.alamofire.autopurgingimagecache-%@", [[NSUUID UUID] UUIDString]];
|
||||
self.synchronizationQueue = dispatch_queue_create([queueName cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_CONCURRENT);
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(removeAllImages)
|
||||
name:UIApplicationDidReceiveMemoryWarningNotification
|
||||
object:nil];
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (UInt64)memoryUsage {
|
||||
__block UInt64 result = 0;
|
||||
dispatch_sync(self.synchronizationQueue, ^{
|
||||
result = self.currentMemoryUsage;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier {
|
||||
dispatch_barrier_async(self.synchronizationQueue, ^{
|
||||
AFCachedImage *cacheImage = [[AFCachedImage alloc] initWithImage:image identifier:identifier];
|
||||
|
||||
AFCachedImage *previousCachedImage = self.cachedImages[identifier];
|
||||
if (previousCachedImage != nil) {
|
||||
self.currentMemoryUsage -= previousCachedImage.totalBytes;
|
||||
}
|
||||
|
||||
self.cachedImages[identifier] = cacheImage;
|
||||
self.currentMemoryUsage += cacheImage.totalBytes;
|
||||
});
|
||||
|
||||
dispatch_barrier_async(self.synchronizationQueue, ^{
|
||||
if (self.currentMemoryUsage > self.memoryCapacity) {
|
||||
UInt64 bytesToPurge = self.currentMemoryUsage - self.preferredMemoryUsageAfterPurge;
|
||||
NSMutableArray <AFCachedImage*> *sortedImages = [NSMutableArray arrayWithArray:self.cachedImages.allValues];
|
||||
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastAccessDate"
|
||||
ascending:YES];
|
||||
[sortedImages sortUsingDescriptors:@[sortDescriptor]];
|
||||
|
||||
UInt64 bytesPurged = 0;
|
||||
|
||||
for (AFCachedImage *cachedImage in sortedImages) {
|
||||
[self.cachedImages removeObjectForKey:cachedImage.identifier];
|
||||
bytesPurged += cachedImage.totalBytes;
|
||||
if (bytesPurged >= bytesToPurge) {
|
||||
break ;
|
||||
}
|
||||
}
|
||||
self.currentMemoryUsage -= bytesPurged;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)removeImageWithIdentifier:(NSString *)identifier {
|
||||
__block BOOL removed = NO;
|
||||
dispatch_barrier_sync(self.synchronizationQueue, ^{
|
||||
AFCachedImage *cachedImage = self.cachedImages[identifier];
|
||||
if (cachedImage != nil) {
|
||||
[self.cachedImages removeObjectForKey:identifier];
|
||||
self.currentMemoryUsage -= cachedImage.totalBytes;
|
||||
removed = YES;
|
||||
}
|
||||
});
|
||||
return removed;
|
||||
}
|
||||
|
||||
- (BOOL)removeAllImages {
|
||||
__block BOOL removed = NO;
|
||||
dispatch_barrier_sync(self.synchronizationQueue, ^{
|
||||
if (self.cachedImages.count > 0) {
|
||||
[self.cachedImages removeAllObjects];
|
||||
self.currentMemoryUsage = 0;
|
||||
removed = YES;
|
||||
}
|
||||
});
|
||||
return removed;
|
||||
}
|
||||
|
||||
- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier {
|
||||
__block UIImage *image = nil;
|
||||
dispatch_sync(self.synchronizationQueue, ^{
|
||||
AFCachedImage *cachedImage = self.cachedImages[identifier];
|
||||
image = [cachedImage accessImage];
|
||||
});
|
||||
return image;
|
||||
}
|
||||
|
||||
- (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
|
||||
[self addImage:image withIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
|
||||
}
|
||||
|
||||
- (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
|
||||
return [self removeImageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
|
||||
}
|
||||
|
||||
- (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
|
||||
return [self imageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
|
||||
}
|
||||
|
||||
- (NSString *)imageCacheKeyFromURLRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)additionalIdentifier {
|
||||
NSString *key = request.URL.absoluteString;
|
||||
if (additionalIdentifier != nil) {
|
||||
key = [key stringByAppendingString:additionalIdentifier];
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
// AFImageDownloader.h
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "AFAutoPurgingImageCache.h"
|
||||
#import "AFHTTPSessionManager.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSInteger, AFImageDownloadPrioritization) {
|
||||
AFImageDownloadPrioritizationFIFO,
|
||||
AFImageDownloadPrioritizationLIFO
|
||||
};
|
||||
|
||||
/**
|
||||
The `AFImageDownloadReceipt` is an object vended by the `AFImageDownloader` when starting a data task. It can be used to cancel active tasks running on the `AFImageDownloader` session. As a general rule, image data tasks should be cancelled using the `AFImageDownloadReceipt` instead of calling `cancel` directly on the `task` itself. The `AFImageDownloader` is optimized to handle duplicate task scenarios as well as pending versus active downloads.
|
||||
*/
|
||||
@interface AFImageDownloadReceipt : NSObject
|
||||
|
||||
/**
|
||||
The data task created by the `AFImageDownloader`.
|
||||
*/
|
||||
@property (nonatomic, strong) NSURLSessionDataTask *task;
|
||||
|
||||
/**
|
||||
The unique identifier for the success and failure blocks when duplicate requests are made.
|
||||
*/
|
||||
@property (nonatomic, strong) NSUUID *receiptID;
|
||||
@end
|
||||
|
||||
/** The `AFImageDownloader` class is responsible for downloading images in parallel on a prioritized queue. Incoming downloads are added to the front or back of the queue depending on the download prioritization. Each downloaded image is cached in the underlying `NSURLCache` as well as the in-memory image cache. By default, any download request with a cached image equivalent in the image cache will automatically be served the cached image representation.
|
||||
*/
|
||||
@interface AFImageDownloader : NSObject
|
||||
|
||||
/**
|
||||
The image cache used to store all downloaded images in. `AFAutoPurgingImageCache` by default.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) id <AFImageRequestCache> imageCache;
|
||||
|
||||
/**
|
||||
The `AFHTTPSessionManager` used to download images. By default, this is configured with an `AFImageResponseSerializer`, and a shared `NSURLCache` for all image downloads.
|
||||
*/
|
||||
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;
|
||||
|
||||
/**
|
||||
Defines the order prioritization of incoming download requests being inserted into the queue. `AFImageDownloadPrioritizationFIFO` by default.
|
||||
*/
|
||||
@property (nonatomic, assign) AFImageDownloadPrioritization downloadPrioritizaton;
|
||||
|
||||
/**
|
||||
The shared default instance of `AFImageDownloader` initialized with default values.
|
||||
*/
|
||||
+ (instancetype)defaultInstance;
|
||||
|
||||
/**
|
||||
Creates a default `NSURLCache` with common usage parameter values.
|
||||
|
||||
@returns The default `NSURLCache` instance.
|
||||
*/
|
||||
+ (NSURLCache *)defaultURLCache;
|
||||
|
||||
/**
|
||||
Default initializer
|
||||
|
||||
@return An instance of `AFImageDownloader` initialized with default values.
|
||||
*/
|
||||
- (instancetype)init;
|
||||
|
||||
/**
|
||||
Initializes the `AFImageDownloader` instance with the given session manager, download prioritization, maximum active download count and image cache.
|
||||
|
||||
@param sessionManager The session manager to use to download images.
|
||||
@param downloadPrioritization The download prioritization of the download queue.
|
||||
@param maximumActiveDownloads The maximum number of active downloads allowed at any given time. Recommend `4`.
|
||||
@param imageCache The image cache used to store all downloaded images in.
|
||||
|
||||
@return The new `AFImageDownloader` instance.
|
||||
*/
|
||||
- (instancetype)initWithSessionManager:(AFHTTPSessionManager *)sessionManager
|
||||
downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization
|
||||
maximumActiveDownloads:(NSInteger)maximumActiveDownloads
|
||||
imageCache:(nullable id <AFImageRequestCache>)imageCache;
|
||||
|
||||
/**
|
||||
Creates a data task using the `sessionManager` instance for the specified URL request.
|
||||
|
||||
If the same data task is already in the queue or currently being downloaded, the success and failure blocks are
|
||||
appended to the already existing task. Once the task completes, all success or failure blocks attached to the
|
||||
task are executed in the order they were added.
|
||||
|
||||
@param request The URL request.
|
||||
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
|
||||
|
||||
@return The image download receipt for the data task if available. `nil` if the image is stored in the cache.
|
||||
cache and the URL request cache policy allows the cache to be used.
|
||||
*/
|
||||
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Creates a data task using the `sessionManager` instance for the specified URL request.
|
||||
|
||||
If the same data task is already in the queue or currently being downloaded, the success and failure blocks are
|
||||
appended to the already existing task. Once the task completes, all success or failure blocks attached to the
|
||||
task are executed in the order they were added.
|
||||
|
||||
@param request The URL request.
|
||||
@param receiptID The identifier to use for the download receipt that will be created for this request. This must be a unique identifier that does not represent any other request.
|
||||
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
|
||||
|
||||
@return The image download receipt for the data task if available. `nil` if the image is stored in the cache.
|
||||
cache and the URL request cache policy allows the cache to be used.
|
||||
*/
|
||||
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
|
||||
withReceiptID:(NSUUID *)receiptID
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Cancels the data task in the receipt by removing the corresponding success and failure blocks and cancelling the data task if necessary.
|
||||
|
||||
If the data task is pending in the queue, it will be cancelled if no other success and failure blocks are registered with the data task. If the data task is currently executing or is already completed, the success and failure blocks are removed and will not be called when the task finishes.
|
||||
|
||||
@param imageDownloadReceipt The image download receipt to cancel.
|
||||
*/
|
||||
- (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+391
@@ -0,0 +1,391 @@
|
||||
// AFImageDownloader.m
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import "AFImageDownloader.h"
|
||||
#import "AFHTTPSessionManager.h"
|
||||
|
||||
@interface AFImageDownloaderResponseHandler : NSObject
|
||||
@property (nonatomic, strong) NSUUID *uuid;
|
||||
@property (nonatomic, copy) void (^successBlock)(NSURLRequest*, NSHTTPURLResponse*, UIImage*);
|
||||
@property (nonatomic, copy) void (^failureBlock)(NSURLRequest*, NSHTTPURLResponse*, NSError*);
|
||||
@end
|
||||
|
||||
@implementation AFImageDownloaderResponseHandler
|
||||
|
||||
- (instancetype)initWithUUID:(NSUUID *)uuid
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure {
|
||||
if (self = [self init]) {
|
||||
self.uuid = uuid;
|
||||
self.successBlock = success;
|
||||
self.failureBlock = failure;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat: @"<AFImageDownloaderResponseHandler>UUID: %@", [self.uuid UUIDString]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface AFImageDownloaderMergedTask : NSObject
|
||||
@property (nonatomic, strong) NSString *URLIdentifier;
|
||||
@property (nonatomic, strong) NSUUID *identifier;
|
||||
@property (nonatomic, strong) NSURLSessionDataTask *task;
|
||||
@property (nonatomic, strong) NSMutableArray <AFImageDownloaderResponseHandler*> *responseHandlers;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AFImageDownloaderMergedTask
|
||||
|
||||
- (instancetype)initWithURLIdentifier:(NSString *)URLIdentifier identifier:(NSUUID *)identifier task:(NSURLSessionDataTask *)task {
|
||||
if (self = [self init]) {
|
||||
self.URLIdentifier = URLIdentifier;
|
||||
self.task = task;
|
||||
self.identifier = identifier;
|
||||
self.responseHandlers = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addResponseHandler:(AFImageDownloaderResponseHandler*)handler {
|
||||
[self.responseHandlers addObject:handler];
|
||||
}
|
||||
|
||||
- (void)removeResponseHandler:(AFImageDownloaderResponseHandler*)handler {
|
||||
[self.responseHandlers removeObject:handler];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation AFImageDownloadReceipt
|
||||
|
||||
- (instancetype)initWithReceiptID:(NSUUID *)receiptID task:(NSURLSessionDataTask *)task {
|
||||
if (self = [self init]) {
|
||||
self.receiptID = receiptID;
|
||||
self.task = task;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface AFImageDownloader ()
|
||||
|
||||
@property (nonatomic, strong) dispatch_queue_t synchronizationQueue;
|
||||
@property (nonatomic, strong) dispatch_queue_t responseQueue;
|
||||
|
||||
@property (nonatomic, assign) NSInteger maximumActiveDownloads;
|
||||
@property (nonatomic, assign) NSInteger activeRequestCount;
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *queuedMergedTasks;
|
||||
@property (nonatomic, strong) NSMutableDictionary *mergedTasks;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation AFImageDownloader
|
||||
|
||||
+ (NSURLCache *)defaultURLCache {
|
||||
return [[NSURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024
|
||||
diskCapacity:150 * 1024 * 1024
|
||||
diskPath:@"com.alamofire.imagedownloader"];
|
||||
}
|
||||
|
||||
+ (NSURLSessionConfiguration *)defaultURLSessionConfiguration {
|
||||
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
|
||||
//TODO set the default HTTP headers
|
||||
|
||||
configuration.HTTPShouldSetCookies = YES;
|
||||
configuration.HTTPShouldUsePipelining = NO;
|
||||
|
||||
configuration.requestCachePolicy = NSURLRequestUseProtocolCachePolicy;
|
||||
configuration.allowsCellularAccess = YES;
|
||||
configuration.timeoutIntervalForRequest = 60.0;
|
||||
configuration.URLCache = [AFImageDownloader defaultURLCache];
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
NSURLSessionConfiguration *defaultConfiguration = [self.class defaultURLSessionConfiguration];
|
||||
AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:defaultConfiguration];
|
||||
sessionManager.responseSerializer = [AFImageResponseSerializer serializer];
|
||||
|
||||
return [self initWithSessionManager:sessionManager
|
||||
downloadPrioritization:AFImageDownloadPrioritizationFIFO
|
||||
maximumActiveDownloads:4
|
||||
imageCache:[[AFAutoPurgingImageCache alloc] init]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithSessionManager:(AFHTTPSessionManager *)sessionManager
|
||||
downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization
|
||||
maximumActiveDownloads:(NSInteger)maximumActiveDownloads
|
||||
imageCache:(id <AFImageRequestCache>)imageCache {
|
||||
if (self = [super init]) {
|
||||
self.sessionManager = sessionManager;
|
||||
|
||||
self.downloadPrioritizaton = downloadPrioritization;
|
||||
self.maximumActiveDownloads = maximumActiveDownloads;
|
||||
self.imageCache = imageCache;
|
||||
|
||||
self.queuedMergedTasks = [[NSMutableArray alloc] init];
|
||||
self.mergedTasks = [[NSMutableDictionary alloc] init];
|
||||
self.activeRequestCount = 0;
|
||||
|
||||
NSString *name = [NSString stringWithFormat:@"com.alamofire.imagedownloader.synchronizationqueue-%@", [[NSUUID UUID] UUIDString]];
|
||||
self.synchronizationQueue = dispatch_queue_create([name cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
name = [NSString stringWithFormat:@"com.alamofire.imagedownloader.responsequeue-%@", [[NSUUID UUID] UUIDString]];
|
||||
self.responseQueue = dispatch_queue_create([name cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_CONCURRENT);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)defaultInstance {
|
||||
static AFImageDownloader *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
|
||||
success:(void (^)(NSURLRequest * _Nonnull, NSHTTPURLResponse * _Nullable, UIImage * _Nonnull))success
|
||||
failure:(void (^)(NSURLRequest * _Nonnull, NSHTTPURLResponse * _Nullable, NSError * _Nonnull))failure {
|
||||
return [self downloadImageForURLRequest:request withReceiptID:[NSUUID UUID] success:success failure:failure];
|
||||
}
|
||||
|
||||
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
|
||||
withReceiptID:(nonnull NSUUID *)receiptID
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure {
|
||||
__block NSURLSessionDataTask *task = nil;
|
||||
dispatch_sync(self.synchronizationQueue, ^{
|
||||
NSString *URLIdentifier = request.URL.absoluteString;
|
||||
if (URLIdentifier == nil) {
|
||||
if (failure) {
|
||||
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorBadURL userInfo:nil];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
failure(request, nil, error);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 1) Append the success and failure blocks to a pre-existing request if it already exists
|
||||
AFImageDownloaderMergedTask *existingMergedTask = self.mergedTasks[URLIdentifier];
|
||||
if (existingMergedTask != nil) {
|
||||
AFImageDownloaderResponseHandler *handler = [[AFImageDownloaderResponseHandler alloc] initWithUUID:receiptID success:success failure:failure];
|
||||
[existingMergedTask addResponseHandler:handler];
|
||||
task = existingMergedTask.task;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) Attempt to load the image from the image cache if the cache policy allows it
|
||||
switch (request.cachePolicy) {
|
||||
case NSURLRequestUseProtocolCachePolicy:
|
||||
case NSURLRequestReturnCacheDataElseLoad:
|
||||
case NSURLRequestReturnCacheDataDontLoad: {
|
||||
UIImage *cachedImage = [self.imageCache imageforRequest:request withAdditionalIdentifier:nil];
|
||||
if (cachedImage != nil) {
|
||||
if (success) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
success(request, nil, cachedImage);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 3) Create the request and set up authentication, validation and response serialization
|
||||
NSUUID *mergedTaskIdentifier = [NSUUID UUID];
|
||||
NSURLSessionDataTask *createdTask;
|
||||
__weak __typeof__(self) weakSelf = self;
|
||||
|
||||
createdTask = [self.sessionManager
|
||||
dataTaskWithRequest:request
|
||||
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
|
||||
dispatch_async(self.responseQueue, ^{
|
||||
__strong __typeof__(weakSelf) strongSelf = weakSelf;
|
||||
AFImageDownloaderMergedTask *mergedTask = self.mergedTasks[URLIdentifier];
|
||||
if ([mergedTask.identifier isEqual:mergedTaskIdentifier]) {
|
||||
mergedTask = [strongSelf safelyRemoveMergedTaskWithURLIdentifier:URLIdentifier];
|
||||
if (error) {
|
||||
for (AFImageDownloaderResponseHandler *handler in mergedTask.responseHandlers) {
|
||||
if (handler.failureBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
handler.failureBlock(request, (NSHTTPURLResponse*)response, error);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
[strongSelf.imageCache addImage:responseObject forRequest:request withAdditionalIdentifier:nil];
|
||||
|
||||
for (AFImageDownloaderResponseHandler *handler in mergedTask.responseHandlers) {
|
||||
if (handler.successBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
handler.successBlock(request, (NSHTTPURLResponse*)response, responseObject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
[strongSelf safelyDecrementActiveTaskCount];
|
||||
[strongSelf safelyStartNextTaskIfNecessary];
|
||||
});
|
||||
}];
|
||||
|
||||
// 4) Store the response handler for use when the request completes
|
||||
AFImageDownloaderResponseHandler *handler = [[AFImageDownloaderResponseHandler alloc] initWithUUID:receiptID
|
||||
success:success
|
||||
failure:failure];
|
||||
AFImageDownloaderMergedTask *mergedTask = [[AFImageDownloaderMergedTask alloc]
|
||||
initWithURLIdentifier:URLIdentifier
|
||||
identifier:mergedTaskIdentifier
|
||||
task:createdTask];
|
||||
[mergedTask addResponseHandler:handler];
|
||||
self.mergedTasks[URLIdentifier] = mergedTask;
|
||||
|
||||
// 5) Either start the request or enqueue it depending on the current active request count
|
||||
if ([self isActiveRequestCountBelowMaximumLimit]) {
|
||||
[self startMergedTask:mergedTask];
|
||||
} else {
|
||||
[self enqueueMergedTask:mergedTask];
|
||||
}
|
||||
|
||||
task = mergedTask.task;
|
||||
});
|
||||
if (task) {
|
||||
return [[AFImageDownloadReceipt alloc] initWithReceiptID:receiptID task:task];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt {
|
||||
dispatch_sync(self.synchronizationQueue, ^{
|
||||
NSString *URLIdentifier = imageDownloadReceipt.task.originalRequest.URL.absoluteString;
|
||||
AFImageDownloaderMergedTask *mergedTask = self.mergedTasks[URLIdentifier];
|
||||
NSUInteger index = [mergedTask.responseHandlers indexOfObjectPassingTest:^BOOL(AFImageDownloaderResponseHandler * _Nonnull handler, __unused NSUInteger idx, __unused BOOL * _Nonnull stop) {
|
||||
return handler.uuid == imageDownloadReceipt.receiptID;
|
||||
}];
|
||||
|
||||
if (index != NSNotFound) {
|
||||
AFImageDownloaderResponseHandler *handler = mergedTask.responseHandlers[index];
|
||||
[mergedTask removeResponseHandler:handler];
|
||||
NSString *failureReason = [NSString stringWithFormat:@"ImageDownloader cancelled URL request: %@",imageDownloadReceipt.task.originalRequest.URL.absoluteString];
|
||||
NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey:failureReason};
|
||||
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo];
|
||||
if (handler.failureBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
handler.failureBlock(imageDownloadReceipt.task.originalRequest, nil, error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (mergedTask.responseHandlers.count == 0 && mergedTask.task.state == NSURLSessionTaskStateSuspended) {
|
||||
[mergedTask.task cancel];
|
||||
[self removeMergedTaskWithURLIdentifier:URLIdentifier];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (AFImageDownloaderMergedTask*)safelyRemoveMergedTaskWithURLIdentifier:(NSString *)URLIdentifier {
|
||||
__block AFImageDownloaderMergedTask *mergedTask = nil;
|
||||
dispatch_sync(self.synchronizationQueue, ^{
|
||||
mergedTask = [self removeMergedTaskWithURLIdentifier:URLIdentifier];
|
||||
});
|
||||
return mergedTask;
|
||||
}
|
||||
|
||||
//This method should only be called from safely within the synchronizationQueue
|
||||
- (AFImageDownloaderMergedTask *)removeMergedTaskWithURLIdentifier:(NSString *)URLIdentifier {
|
||||
AFImageDownloaderMergedTask *mergedTask = self.mergedTasks[URLIdentifier];
|
||||
[self.mergedTasks removeObjectForKey:URLIdentifier];
|
||||
return mergedTask;
|
||||
}
|
||||
|
||||
- (void)safelyDecrementActiveTaskCount {
|
||||
dispatch_sync(self.synchronizationQueue, ^{
|
||||
if (self.activeRequestCount > 0) {
|
||||
self.activeRequestCount -= 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)safelyStartNextTaskIfNecessary {
|
||||
dispatch_sync(self.synchronizationQueue, ^{
|
||||
if ([self isActiveRequestCountBelowMaximumLimit]) {
|
||||
while (self.queuedMergedTasks.count > 0) {
|
||||
AFImageDownloaderMergedTask *mergedTask = [self dequeueMergedTask];
|
||||
if (mergedTask.task.state == NSURLSessionTaskStateSuspended) {
|
||||
[self startMergedTask:mergedTask];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)startMergedTask:(AFImageDownloaderMergedTask *)mergedTask {
|
||||
[mergedTask.task resume];
|
||||
++self.activeRequestCount;
|
||||
}
|
||||
|
||||
- (void)enqueueMergedTask:(AFImageDownloaderMergedTask *)mergedTask {
|
||||
switch (self.downloadPrioritizaton) {
|
||||
case AFImageDownloadPrioritizationFIFO:
|
||||
[self.queuedMergedTasks addObject:mergedTask];
|
||||
break;
|
||||
case AFImageDownloadPrioritizationLIFO:
|
||||
[self.queuedMergedTasks insertObject:mergedTask atIndex:0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (AFImageDownloaderMergedTask *)dequeueMergedTask {
|
||||
AFImageDownloaderMergedTask *mergedTask = nil;
|
||||
mergedTask = [self.queuedMergedTasks firstObject];
|
||||
[self.queuedMergedTasks removeObject:mergedTask];
|
||||
return mergedTask;
|
||||
}
|
||||
|
||||
- (BOOL)isActiveRequestCountBelowMaximumLimit {
|
||||
return self.activeRequestCount < self.maximumActiveDownloads;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
ios/SAPTracker/src/xcode/SAPTracker/Libraries/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h
Regular → Executable
+29
-6
@@ -1,5 +1,5 @@
|
||||
// AFNetworkActivityIndicatorManager.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,16 +21,16 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a network request operation has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
|
||||
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
|
||||
|
||||
You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code:
|
||||
|
||||
@@ -52,9 +52,25 @@ NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropri
|
||||
@property (nonatomic, assign, getter = isEnabled) BOOL enabled;
|
||||
|
||||
/**
|
||||
A Boolean value indicating whether the network activity indicator is currently displayed in the status bar.
|
||||
A Boolean value indicating whether the network activity indicator manager is currently active.
|
||||
*/
|
||||
@property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
|
||||
|
||||
/**
|
||||
A time interval indicating the minimum duration of networking activity that should occur before the activity indicator is displayed. The default value 1 second. If the network activity indicator should be displayed immediately when network activity occurs, this value should be set to 0 seconds.
|
||||
|
||||
Apple's HIG describes the following:
|
||||
|
||||
> Display the network activity indicator to provide feedback when your app accesses the network for more than a couple of seconds. If the operation finishes sooner than that, you don’t have to show the network activity indicator, because the indicator is likely to disappear before users notice its presence.
|
||||
|
||||
*/
|
||||
@property (readonly, nonatomic, assign) BOOL isNetworkActivityIndicatorVisible;
|
||||
@property (nonatomic, assign) NSTimeInterval activationDelay;
|
||||
|
||||
/**
|
||||
A time interval indicating the duration of time of no networking activity required before the activity indicator is disabled. This allows for continuous display of the network activity indicator across multiple requests. The default value is 0.17 seconds.
|
||||
*/
|
||||
|
||||
@property (nonatomic, assign) NSTimeInterval completionDelay;
|
||||
|
||||
/**
|
||||
Returns the shared network activity indicator manager object for the system.
|
||||
@@ -73,6 +89,13 @@ NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropri
|
||||
*/
|
||||
- (void)decrementActivityCount;
|
||||
|
||||
/**
|
||||
Set the a custom method to be executed when the network activity indicator manager should be hidden/shown. By default, this is null, and the UIApplication Network Activity Indicator will be managed automatically. If this block is set, it is the responsiblity of the caller to manager the network activity indicator going forward.
|
||||
|
||||
@param block A block to be executed when the network activity indicator status changes.
|
||||
*/
|
||||
- (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
ios/SAPTracker/src/xcode/SAPTracker/Libraries/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m
Regular → Executable
+141
-50
@@ -1,5 +1,5 @@
|
||||
// AFNetworkActivityIndicatorManager.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,41 +21,42 @@
|
||||
|
||||
#import "AFNetworkActivityIndicatorManager.h"
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED)
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
|
||||
#if TARGET_OS_IOS
|
||||
#import "AFURLSessionManager.h"
|
||||
#endif
|
||||
|
||||
static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.17;
|
||||
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
|
||||
AFNetworkActivityManagerStateNotActive,
|
||||
AFNetworkActivityManagerStateDelayingStart,
|
||||
AFNetworkActivityManagerStateActive,
|
||||
AFNetworkActivityManagerStateDelayingEnd
|
||||
};
|
||||
|
||||
static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0;
|
||||
static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17;
|
||||
|
||||
static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notification) {
|
||||
if ([[notification object] isKindOfClass:[AFURLConnectionOperation class]]) {
|
||||
return [(AFURLConnectionOperation *)[notification object] request];
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
|
||||
if ([[notification object] respondsToSelector:@selector(originalRequest)]) {
|
||||
return [(NSURLSessionTask *)[notification object] originalRequest];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
typedef void (^AFNetworkActivityActionBlock)(BOOL networkActivityIndicatorVisible);
|
||||
|
||||
@interface AFNetworkActivityIndicatorManager ()
|
||||
@property (readwrite, nonatomic, assign) NSInteger activityCount;
|
||||
@property (readwrite, nonatomic, strong) NSTimer *activityIndicatorVisibilityTimer;
|
||||
@property (readonly, nonatomic, getter = isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
|
||||
@property (readwrite, nonatomic, strong) NSTimer *activationDelayTimer;
|
||||
@property (readwrite, nonatomic, strong) NSTimer *completionDelayTimer;
|
||||
@property (readonly, nonatomic, getter = isNetworkActivityOccurring) BOOL networkActivityOccurring;
|
||||
@property (nonatomic, copy) AFNetworkActivityActionBlock networkActivityActionBlock;
|
||||
@property (nonatomic, assign) AFNetworkActivityManagerState currentState;
|
||||
@property (nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
|
||||
|
||||
- (void)updateNetworkActivityIndicatorVisibility;
|
||||
- (void)updateNetworkActivityIndicatorVisibilityDelayed;
|
||||
- (void)updateCurrentStateForNetworkActivityChange;
|
||||
@end
|
||||
|
||||
@implementation AFNetworkActivityIndicatorManager
|
||||
@dynamic networkActivityIndicatorVisible;
|
||||
|
||||
+ (instancetype)sharedManager {
|
||||
static AFNetworkActivityIndicatorManager *_sharedManager = nil;
|
||||
@@ -67,24 +68,17 @@ static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notificat
|
||||
return _sharedManager;
|
||||
}
|
||||
|
||||
+ (NSSet *)keyPathsForValuesAffectingIsNetworkActivityIndicatorVisible {
|
||||
return [NSSet setWithObject:@"activityCount"];
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingOperationDidStartNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingOperationDidFinishNotification object:nil];
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
|
||||
self.currentState = AFNetworkActivityManagerStateNotActive;
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidSuspendNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil];
|
||||
#endif
|
||||
self.activationDelay = kDefaultAFNetworkActivityManagerActivationDelay;
|
||||
self.completionDelay = kDefaultAFNetworkActivityManagerCompletionDelay;
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -92,28 +86,40 @@ static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notificat
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[_activityIndicatorVisibilityTimer invalidate];
|
||||
[_activationDelayTimer invalidate];
|
||||
[_completionDelayTimer invalidate];
|
||||
}
|
||||
|
||||
- (void)updateNetworkActivityIndicatorVisibilityDelayed {
|
||||
if (self.enabled) {
|
||||
// Delay hiding of activity indicator for a short interval, to avoid flickering
|
||||
if (![self isNetworkActivityIndicatorVisible]) {
|
||||
[self.activityIndicatorVisibilityTimer invalidate];
|
||||
self.activityIndicatorVisibilityTimer = [NSTimer timerWithTimeInterval:kAFNetworkActivityIndicatorInvisibilityDelay target:self selector:@selector(updateNetworkActivityIndicatorVisibility) userInfo:nil repeats:NO];
|
||||
[[NSRunLoop mainRunLoop] addTimer:self.activityIndicatorVisibilityTimer forMode:NSRunLoopCommonModes];
|
||||
} else {
|
||||
[self performSelectorOnMainThread:@selector(updateNetworkActivityIndicatorVisibility) withObject:nil waitUntilDone:NO modes:@[NSRunLoopCommonModes]];
|
||||
}
|
||||
- (void)setEnabled:(BOOL)enabled {
|
||||
_enabled = enabled;
|
||||
if (enabled == NO) {
|
||||
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isNetworkActivityIndicatorVisible {
|
||||
return self.activityCount > 0;
|
||||
- (void)setNetworkingActivityActionWithBlock:(void (^)(BOOL networkActivityIndicatorVisible))block {
|
||||
self.networkActivityActionBlock = block;
|
||||
}
|
||||
|
||||
- (void)updateNetworkActivityIndicatorVisibility {
|
||||
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]];
|
||||
- (BOOL)isNetworkActivityOccurring {
|
||||
@synchronized(self) {
|
||||
return self.activityCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setNetworkActivityIndicatorVisible:(BOOL)networkActivityIndicatorVisible {
|
||||
if (_networkActivityIndicatorVisible != networkActivityIndicatorVisible) {
|
||||
[self willChangeValueForKey:@"networkActivityIndicatorVisible"];
|
||||
@synchronized(self) {
|
||||
_networkActivityIndicatorVisible = networkActivityIndicatorVisible;
|
||||
}
|
||||
[self didChangeValueForKey:@"networkActivityIndicatorVisible"];
|
||||
if (self.networkActivityActionBlock) {
|
||||
self.networkActivityActionBlock(networkActivityIndicatorVisible);
|
||||
} else {
|
||||
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:networkActivityIndicatorVisible];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setActivityCount:(NSInteger)activityCount {
|
||||
@@ -122,7 +128,7 @@ static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notificat
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateNetworkActivityIndicatorVisibilityDelayed];
|
||||
[self updateCurrentStateForNetworkActivityChange];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -134,7 +140,7 @@ static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notificat
|
||||
[self didChangeValueForKey:@"activityCount"];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateNetworkActivityIndicatorVisibilityDelayed];
|
||||
[self updateCurrentStateForNetworkActivityChange];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,7 +155,7 @@ static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notificat
|
||||
[self didChangeValueForKey:@"activityCount"];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateNetworkActivityIndicatorVisibilityDelayed];
|
||||
[self updateCurrentStateForNetworkActivityChange];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -165,6 +171,91 @@ static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notificat
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Internal State Management
|
||||
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
|
||||
@synchronized(self) {
|
||||
if (_currentState != currentState) {
|
||||
[self willChangeValueForKey:@"currentState"];
|
||||
_currentState = currentState;
|
||||
switch (currentState) {
|
||||
case AFNetworkActivityManagerStateNotActive:
|
||||
[self cancelActivationDelayTimer];
|
||||
[self cancelCompletionDelayTimer];
|
||||
[self setNetworkActivityIndicatorVisible:NO];
|
||||
break;
|
||||
case AFNetworkActivityManagerStateDelayingStart:
|
||||
[self startActivationDelayTimer];
|
||||
break;
|
||||
case AFNetworkActivityManagerStateActive:
|
||||
[self cancelCompletionDelayTimer];
|
||||
[self setNetworkActivityIndicatorVisible:YES];
|
||||
break;
|
||||
case AFNetworkActivityManagerStateDelayingEnd:
|
||||
[self startCompletionDelayTimer];
|
||||
break;
|
||||
}
|
||||
}
|
||||
[self didChangeValueForKey:@"currentState"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateCurrentStateForNetworkActivityChange {
|
||||
if (self.enabled) {
|
||||
switch (self.currentState) {
|
||||
case AFNetworkActivityManagerStateNotActive:
|
||||
if (self.isNetworkActivityOccurring) {
|
||||
[self setCurrentState:AFNetworkActivityManagerStateDelayingStart];
|
||||
}
|
||||
break;
|
||||
case AFNetworkActivityManagerStateDelayingStart:
|
||||
//No op. Let the delay timer finish out.
|
||||
break;
|
||||
case AFNetworkActivityManagerStateActive:
|
||||
if (!self.isNetworkActivityOccurring) {
|
||||
[self setCurrentState:AFNetworkActivityManagerStateDelayingEnd];
|
||||
}
|
||||
break;
|
||||
case AFNetworkActivityManagerStateDelayingEnd:
|
||||
if (self.isNetworkActivityOccurring) {
|
||||
[self setCurrentState:AFNetworkActivityManagerStateActive];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startActivationDelayTimer {
|
||||
self.activationDelayTimer = [NSTimer
|
||||
timerWithTimeInterval:self.activationDelay target:self selector:@selector(activationDelayTimerFired) userInfo:nil repeats:NO];
|
||||
[[NSRunLoop mainRunLoop] addTimer:self.activationDelayTimer forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)activationDelayTimerFired {
|
||||
if (self.networkActivityOccurring) {
|
||||
[self setCurrentState:AFNetworkActivityManagerStateActive];
|
||||
} else {
|
||||
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startCompletionDelayTimer {
|
||||
[self.completionDelayTimer invalidate];
|
||||
self.completionDelayTimer = [NSTimer timerWithTimeInterval:self.completionDelay target:self selector:@selector(completionDelayTimerFired) userInfo:nil repeats:NO];
|
||||
[[NSRunLoop mainRunLoop] addTimer:self.completionDelayTimer forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)completionDelayTimerFired {
|
||||
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
|
||||
}
|
||||
|
||||
- (void)cancelActivationDelayTimer {
|
||||
[self.activationDelayTimer invalidate];
|
||||
}
|
||||
|
||||
- (void)cancelCompletionDelayTimer {
|
||||
[self.completionDelayTimer invalidate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
Regular → Executable
+4
-19
@@ -1,5 +1,5 @@
|
||||
// UIActivityIndicatorView+AFNetworking.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,16 +21,14 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class AFURLConnectionOperation;
|
||||
|
||||
/**
|
||||
This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a request operation or session task.
|
||||
This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a session task.
|
||||
*/
|
||||
@interface UIActivityIndicatorView (AFNetworking)
|
||||
|
||||
@@ -43,20 +41,7 @@
|
||||
|
||||
@param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task;
|
||||
#endif
|
||||
|
||||
///---------------------------------------
|
||||
/// @name Animating for Request Operations
|
||||
///---------------------------------------
|
||||
|
||||
/**
|
||||
Binds the animating state to the execution state of the specified operation.
|
||||
|
||||
@param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled.
|
||||
*/
|
||||
- (void)setAnimatingWithStateOfOperation:(nullable AFURLConnectionOperation *)operation;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
Regular → Executable
+2
-49
@@ -1,5 +1,5 @@
|
||||
// UIActivityIndicatorView+AFNetworking.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,22 +22,15 @@
|
||||
#import "UIActivityIndicatorView+AFNetworking.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
#import "AFURLSessionManager.h"
|
||||
#endif
|
||||
|
||||
@interface AFActivityIndicatorViewNotificationObserver : NSObject
|
||||
@property (readonly, nonatomic, weak) UIActivityIndicatorView *activityIndicatorView;
|
||||
- (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView;
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task;
|
||||
#endif
|
||||
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation;
|
||||
|
||||
@end
|
||||
|
||||
@@ -52,15 +45,9 @@
|
||||
return notificationObserver;
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
|
||||
[[self af_notificationObserver] setAnimatingWithStateOfTask:task];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation {
|
||||
[[self af_notificationObserver] setAnimatingWithStateOfOperation:operation];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -75,7 +62,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
@@ -102,34 +88,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
|
||||
|
||||
if (operation) {
|
||||
if (![operation isFinished]) {
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
|
||||
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
|
||||
if ([operation isExecuting]) {
|
||||
[self.activityIndicatorView startAnimating];
|
||||
} else {
|
||||
[self.activityIndicatorView stopAnimating];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
[notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingOperationDidStartNotification object:operation];
|
||||
[notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingOperationDidFinishNotification object:operation];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@@ -156,14 +114,9 @@
|
||||
- (void)dealloc {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
[notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
|
||||
#endif
|
||||
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
// UIAlertView+AFNetworking.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class AFURLConnectionOperation;
|
||||
|
||||
/**
|
||||
This category adds methods to the UIKit framework's `UIAlertView` class. The methods in this category provide support for automatically showing an alert if a session task or request operation finishes with an error. Alert title and message are filled from the corresponding `localizedDescription` & `localizedRecoverySuggestion` or `localizedFailureReason` of the error.
|
||||
*/
|
||||
@interface UIAlertView (AFNetworking)
|
||||
|
||||
///-------------------------------------
|
||||
/// @name Showing Alert for Session Task
|
||||
///-------------------------------------
|
||||
|
||||
/**
|
||||
Shows an alert view with the error of the specified session task, if any.
|
||||
|
||||
@param task The session task.
|
||||
@param delegate The alert view delegate.
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
|
||||
delegate:(nullable id)delegate NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
|
||||
#endif
|
||||
|
||||
/**
|
||||
Shows an alert view with the error of the specified session task, if any, with a custom cancel button title and other button titles.
|
||||
|
||||
@param task The session task.
|
||||
@param delegate The alert view delegate.
|
||||
@param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title.
|
||||
@param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`.
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
|
||||
delegate:(nullable id)delegate
|
||||
cancelButtonTitle:(nullable NSString *)cancelButtonTitle
|
||||
otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
|
||||
#endif
|
||||
|
||||
///------------------------------------------
|
||||
/// @name Showing Alert for Request Operation
|
||||
///------------------------------------------
|
||||
|
||||
/**
|
||||
Shows an alert view with the error of the specified request operation, if any.
|
||||
|
||||
@param operation The request operation.
|
||||
@param delegate The alert view delegate.
|
||||
*/
|
||||
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
|
||||
delegate:(nullable id)delegate NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
|
||||
|
||||
/**
|
||||
Shows an alert view with the error of the specified request operation, if any, with a custom cancel button title and other button titles.
|
||||
|
||||
@param operation The request operation.
|
||||
@param delegate The alert view delegate.
|
||||
@param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title.
|
||||
@param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`.
|
||||
*/
|
||||
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
|
||||
delegate:(nullable id)delegate
|
||||
cancelButtonTitle:(nullable NSString *)cancelButtonTitle
|
||||
otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
// UIAlertView+AFNetworking.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "UIAlertView+AFNetworking.h"
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
|
||||
#import "AFURLConnectionOperation.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
#import "AFURLSessionManager.h"
|
||||
#endif
|
||||
|
||||
static void AFGetAlertViewTitleAndMessageFromError(NSError *error, NSString * __autoreleasing *title, NSString * __autoreleasing *message) {
|
||||
if (error.localizedDescription && (error.localizedRecoverySuggestion || error.localizedFailureReason)) {
|
||||
*title = error.localizedDescription;
|
||||
|
||||
if (error.localizedRecoverySuggestion) {
|
||||
*message = error.localizedRecoverySuggestion;
|
||||
} else {
|
||||
*message = error.localizedFailureReason;
|
||||
}
|
||||
} else if (error.localizedDescription) {
|
||||
*title = NSLocalizedStringFromTable(@"Error", @"AFNetworking", @"Fallback Error Description");
|
||||
*message = error.localizedDescription;
|
||||
} else {
|
||||
*title = NSLocalizedStringFromTable(@"Error", @"AFNetworking", @"Fallback Error Description");
|
||||
*message = [NSString stringWithFormat:NSLocalizedStringFromTable(@"%@ Error: %ld", @"AFNetworking", @"Fallback Error Failure Reason Format"), error.domain, (long)error.code];
|
||||
}
|
||||
}
|
||||
|
||||
@implementation UIAlertView (AFNetworking)
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
|
||||
delegate:(id)delegate
|
||||
{
|
||||
[self showAlertViewForTaskWithErrorOnCompletion:task delegate:delegate cancelButtonTitle:NSLocalizedStringFromTable(@"Dismiss", @"AFNetworking", @"UIAlertView Cancel Button Title") otherButtonTitles:nil, nil];
|
||||
}
|
||||
|
||||
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
|
||||
delegate:(id)delegate
|
||||
cancelButtonTitle:(NSString *)cancelButtonTitle
|
||||
otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION
|
||||
{
|
||||
NSMutableArray *mutableOtherTitles = [NSMutableArray array];
|
||||
va_list otherButtonTitleList;
|
||||
va_start(otherButtonTitleList, otherButtonTitles);
|
||||
{
|
||||
for (NSString *otherButtonTitle = otherButtonTitles; otherButtonTitle != nil; otherButtonTitle = va_arg(otherButtonTitleList, NSString *)) {
|
||||
[mutableOtherTitles addObject:otherButtonTitle];
|
||||
}
|
||||
}
|
||||
va_end(otherButtonTitleList);
|
||||
|
||||
__block __weak id<NSObject> observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingTaskDidCompleteNotification object:task queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
|
||||
NSError *error = notification.userInfo[AFNetworkingTaskDidCompleteErrorKey];
|
||||
if (error) {
|
||||
NSString *title, *message;
|
||||
AFGetAlertViewTitleAndMessageFromError(error, &title, &message);
|
||||
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil];
|
||||
for (NSString *otherButtonTitle in mutableOtherTitles) {
|
||||
[alertView addButtonWithTitle:otherButtonTitle];
|
||||
}
|
||||
[alertView setTitle:title];
|
||||
[alertView setMessage:message];
|
||||
[alertView show];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:observer];
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
|
||||
delegate:(id)delegate
|
||||
{
|
||||
[self showAlertViewForRequestOperationWithErrorOnCompletion:operation delegate:delegate cancelButtonTitle:NSLocalizedStringFromTable(@"Dismiss", @"AFNetworking", @"UIAlertView Cancel Button Title") otherButtonTitles:nil, nil];
|
||||
}
|
||||
|
||||
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
|
||||
delegate:(id)delegate
|
||||
cancelButtonTitle:(NSString *)cancelButtonTitle
|
||||
otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION
|
||||
{
|
||||
NSMutableArray *mutableOtherTitles = [NSMutableArray array];
|
||||
va_list otherButtonTitleList;
|
||||
va_start(otherButtonTitleList, otherButtonTitles);
|
||||
{
|
||||
for (NSString *otherButtonTitle = otherButtonTitles; otherButtonTitle != nil; otherButtonTitle = va_arg(otherButtonTitleList, NSString *)) {
|
||||
[mutableOtherTitles addObject:otherButtonTitle];
|
||||
}
|
||||
}
|
||||
va_end(otherButtonTitleList);
|
||||
|
||||
__block __weak id<NSObject> observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingOperationDidFinishNotification object:operation queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
|
||||
|
||||
if (notification.object && [notification.object isKindOfClass:[AFURLConnectionOperation class]]) {
|
||||
NSError *error = [(AFURLConnectionOperation *)notification.object error];
|
||||
if (error) {
|
||||
NSString *title, *message;
|
||||
AFGetAlertViewTitleAndMessageFromError(error, &title, &message);
|
||||
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil];
|
||||
for (NSString *otherButtonTitle in mutableOtherTitles) {
|
||||
[alertView addButtonWithTitle:otherButtonTitle];
|
||||
}
|
||||
[alertView setTitle:title];
|
||||
[alertView setMessage:message];
|
||||
[alertView show];
|
||||
}
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:observer];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
Regular → Executable
+25
-36
@@ -1,5 +1,5 @@
|
||||
// UIButton+AFNetworking.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,15 +21,15 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol AFURLResponseSerialization, AFImageCache;
|
||||
@class AFImageDownloader;
|
||||
|
||||
/**
|
||||
This category adds methods to the UIKit framework's `UIButton` class. The methods in this category provide support for loading remote images and background images asynchronously from a URL.
|
||||
@@ -38,32 +38,21 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface UIButton (AFNetworking)
|
||||
|
||||
///----------------------------
|
||||
/// @name Accessing Image Cache
|
||||
///----------------------------
|
||||
|
||||
/**
|
||||
The image cache used to improve image loading performance on scroll views. By default, `UIButton` will use the `sharedImageCache` of `UIImageView`.
|
||||
*/
|
||||
+ (id <AFImageCache>)sharedImageCache;
|
||||
|
||||
/**
|
||||
Set the cache used for image loading.
|
||||
|
||||
@param imageCache The image cache.
|
||||
*/
|
||||
+ (void)setSharedImageCache:(__nullable id <AFImageCache>)imageCache;
|
||||
|
||||
///------------------------------------
|
||||
/// @name Accessing Response Serializer
|
||||
/// @name Accessing the Image Downloader
|
||||
///------------------------------------
|
||||
|
||||
/**
|
||||
The response serializer used to create an image representation from the server response and response data. By default, this is an instance of `AFImageResponseSerializer`.
|
||||
Set the shared image downloader used to download images.
|
||||
|
||||
@discussion Subclasses of `AFImageResponseSerializer` could be used to perform post-processing, such as color correction, face detection, or other effects. See https://github.com/AFNetworking/AFCoreImageSerializer
|
||||
@param imageDownloader The shared image downloader used to download images.
|
||||
*/
|
||||
+ (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader;
|
||||
|
||||
/**
|
||||
The shared image downloader used to download images.
|
||||
*/
|
||||
@property (nonatomic, strong) id <AFURLResponseSerialization> imageResponseSerializer;
|
||||
+ (AFImageDownloader *)sharedImageDownloader;
|
||||
|
||||
///--------------------
|
||||
/// @name Setting Image
|
||||
@@ -103,14 +92,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@param state The control state.
|
||||
@param urlRequest The URL request used for the image request.
|
||||
@param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the button will not change its image until the image request finishes.
|
||||
@param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes two arguments: the server response and the image. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes a single argument: the error that occurred.
|
||||
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
|
||||
*/
|
||||
- (void)setImageForState:(UIControlState)state
|
||||
withURLRequest:(NSURLRequest *)urlRequest
|
||||
placeholderImage:(nullable UIImage *)placeholderImage
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
|
||||
|
||||
|
||||
///-------------------------------
|
||||
@@ -151,14 +140,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@param state The control state.
|
||||
@param urlRequest The URL request used for the image request.
|
||||
@param placeholderImage The background image to be set initially, until the background image request finishes. If `nil`, the button will not change its background image until the background image request finishes.
|
||||
@param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes two arguments: the server response and the image. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes a single argument: the error that occurred.
|
||||
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
|
||||
*/
|
||||
- (void)setBackgroundImageForState:(UIControlState)state
|
||||
withURLRequest:(NSURLRequest *)urlRequest
|
||||
placeholderImage:(nullable UIImage *)placeholderImage
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
|
||||
|
||||
|
||||
///------------------------------
|
||||
@@ -166,18 +155,18 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
///------------------------------
|
||||
|
||||
/**
|
||||
Cancels any executing image operation for the specified control state of the receiver, if one exists.
|
||||
Cancels any executing image task for the specified control state of the receiver, if one exists.
|
||||
|
||||
@param state The control state.
|
||||
*/
|
||||
- (void)cancelImageRequestOperationForState:(UIControlState)state;
|
||||
- (void)cancelImageDownloadTaskForState:(UIControlState)state;
|
||||
|
||||
/**
|
||||
Cancels any executing background image operation for the specified control state of the receiver, if one exists.
|
||||
Cancels any executing background image task for the specified control state of the receiver, if one exists.
|
||||
|
||||
@param state The control state.
|
||||
*/
|
||||
- (void)cancelBackgroundImageRequestOperationForState:(UIControlState)state;
|
||||
- (void)cancelBackgroundImageDownloadTaskForState:(UIControlState)state;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
Regular → Executable
+139
-127
@@ -1,5 +1,5 @@
|
||||
// UIButton+AFNetworking.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,89 +23,76 @@
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
|
||||
#import "AFURLResponseSerialization.h"
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import "UIImageView+AFNetworking.h"
|
||||
#import "AFImageDownloader.h"
|
||||
|
||||
@interface UIButton (_AFNetworking)
|
||||
@end
|
||||
|
||||
@implementation UIButton (_AFNetworking)
|
||||
|
||||
+ (NSOperationQueue *)af_sharedImageRequestOperationQueue {
|
||||
static NSOperationQueue *_af_sharedImageRequestOperationQueue = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_af_sharedImageRequestOperationQueue = [[NSOperationQueue alloc] init];
|
||||
_af_sharedImageRequestOperationQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
|
||||
});
|
||||
|
||||
return _af_sharedImageRequestOperationQueue;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static char AFImageRequestOperationNormal;
|
||||
static char AFImageRequestOperationHighlighted;
|
||||
static char AFImageRequestOperationSelected;
|
||||
static char AFImageRequestOperationDisabled;
|
||||
static char AFImageDownloadReceiptNormal;
|
||||
static char AFImageDownloadReceiptHighlighted;
|
||||
static char AFImageDownloadReceiptSelected;
|
||||
static char AFImageDownloadReceiptDisabled;
|
||||
|
||||
static const char * af_imageRequestOperationKeyForState(UIControlState state) {
|
||||
static const char * af_imageDownloadReceiptKeyForState(UIControlState state) {
|
||||
switch (state) {
|
||||
case UIControlStateHighlighted:
|
||||
return &AFImageRequestOperationHighlighted;
|
||||
return &AFImageDownloadReceiptHighlighted;
|
||||
case UIControlStateSelected:
|
||||
return &AFImageRequestOperationSelected;
|
||||
return &AFImageDownloadReceiptSelected;
|
||||
case UIControlStateDisabled:
|
||||
return &AFImageRequestOperationDisabled;
|
||||
return &AFImageDownloadReceiptDisabled;
|
||||
case UIControlStateNormal:
|
||||
default:
|
||||
return &AFImageRequestOperationNormal;
|
||||
return &AFImageDownloadReceiptNormal;
|
||||
}
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)af_imageRequestOperationForState:(UIControlState)state {
|
||||
return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, af_imageRequestOperationKeyForState(state));
|
||||
- (AFImageDownloadReceipt *)af_imageDownloadReceiptForState:(UIControlState)state {
|
||||
return (AFImageDownloadReceipt *)objc_getAssociatedObject(self, af_imageDownloadReceiptKeyForState(state));
|
||||
}
|
||||
|
||||
- (void)af_setImageRequestOperation:(AFHTTPRequestOperation *)imageRequestOperation
|
||||
- (void)af_setImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt
|
||||
forState:(UIControlState)state
|
||||
{
|
||||
objc_setAssociatedObject(self, af_imageRequestOperationKeyForState(state), imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
objc_setAssociatedObject(self, af_imageDownloadReceiptKeyForState(state), imageDownloadReceipt, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static char AFBackgroundImageRequestOperationNormal;
|
||||
static char AFBackgroundImageRequestOperationHighlighted;
|
||||
static char AFBackgroundImageRequestOperationSelected;
|
||||
static char AFBackgroundImageRequestOperationDisabled;
|
||||
static char AFBackgroundImageDownloadReceiptNormal;
|
||||
static char AFBackgroundImageDownloadReceiptHighlighted;
|
||||
static char AFBackgroundImageDownloadReceiptSelected;
|
||||
static char AFBackgroundImageDownloadReceiptDisabled;
|
||||
|
||||
static const char * af_backgroundImageRequestOperationKeyForState(UIControlState state) {
|
||||
static const char * af_backgroundImageDownloadReceiptKeyForState(UIControlState state) {
|
||||
switch (state) {
|
||||
case UIControlStateHighlighted:
|
||||
return &AFBackgroundImageRequestOperationHighlighted;
|
||||
return &AFBackgroundImageDownloadReceiptHighlighted;
|
||||
case UIControlStateSelected:
|
||||
return &AFBackgroundImageRequestOperationSelected;
|
||||
return &AFBackgroundImageDownloadReceiptSelected;
|
||||
case UIControlStateDisabled:
|
||||
return &AFBackgroundImageRequestOperationDisabled;
|
||||
return &AFBackgroundImageDownloadReceiptDisabled;
|
||||
case UIControlStateNormal:
|
||||
default:
|
||||
return &AFBackgroundImageRequestOperationNormal;
|
||||
return &AFBackgroundImageDownloadReceiptNormal;
|
||||
}
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)af_backgroundImageRequestOperationForState:(UIControlState)state {
|
||||
return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, af_backgroundImageRequestOperationKeyForState(state));
|
||||
- (AFImageDownloadReceipt *)af_backgroundImageDownloadReceiptForState:(UIControlState)state {
|
||||
return (AFImageDownloadReceipt *)objc_getAssociatedObject(self, af_backgroundImageDownloadReceiptKeyForState(state));
|
||||
}
|
||||
|
||||
- (void)af_setBackgroundImageRequestOperation:(AFHTTPRequestOperation *)imageRequestOperation
|
||||
- (void)af_setBackgroundImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt
|
||||
forState:(UIControlState)state
|
||||
{
|
||||
objc_setAssociatedObject(self, af_backgroundImageRequestOperationKeyForState(state), imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
objc_setAssociatedObject(self, af_backgroundImageDownloadReceiptKeyForState(state), imageDownloadReceipt, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -114,34 +101,16 @@ static const char * af_backgroundImageRequestOperationKeyForState(UIControlState
|
||||
|
||||
@implementation UIButton (AFNetworking)
|
||||
|
||||
+ (id <AFImageCache>)sharedImageCache {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
return objc_getAssociatedObject(self, @selector(sharedImageCache)) ?: [UIImageView sharedImageCache];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
+ (void)setSharedImageCache:(__nullable id <AFImageCache>)imageCache {
|
||||
objc_setAssociatedObject(self, @selector(sharedImageCache), imageCache, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (id <AFURLResponseSerialization>)imageResponseSerializer {
|
||||
static id <AFURLResponseSerialization> _af_defaultImageResponseSerializer = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_af_defaultImageResponseSerializer = [AFImageResponseSerializer serializer];
|
||||
});
|
||||
+ (AFImageDownloader *)sharedImageDownloader {
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
return objc_getAssociatedObject(self, @selector(imageResponseSerializer)) ?: _af_defaultImageResponseSerializer;
|
||||
return objc_getAssociatedObject(self, @selector(sharedImageDownloader)) ?: [AFImageDownloader defaultInstance];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
- (void)setImageResponseSerializer:(id <AFURLResponseSerialization>)serializer {
|
||||
objc_setAssociatedObject(self, @selector(imageResponseSerializer), serializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
+ (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader {
|
||||
objc_setAssociatedObject(self, @selector(sharedImageDownloader), imageDownloader, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -164,49 +133,62 @@ static const char * af_backgroundImageRequestOperationKeyForState(UIControlState
|
||||
|
||||
- (void)setImageForState:(UIControlState)state
|
||||
withURLRequest:(NSURLRequest *)urlRequest
|
||||
placeholderImage:(UIImage *)placeholderImage
|
||||
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
|
||||
failure:(void (^)(NSError *error))failure
|
||||
placeholderImage:(nullable UIImage *)placeholderImage
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure
|
||||
{
|
||||
[self cancelImageRequestOperationForState:state];
|
||||
if ([self isActiveTaskURLEqualToURLRequest:urlRequest forState:state]) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIImage *cachedImage = [[[self class] sharedImageCache] cachedImageForRequest:urlRequest];
|
||||
[self cancelImageDownloadTaskForState:state];
|
||||
|
||||
AFImageDownloader *downloader = [[self class] sharedImageDownloader];
|
||||
id <AFImageRequestCache> imageCache = downloader.imageCache;
|
||||
|
||||
//Use the image from the image cache if it exists
|
||||
UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
|
||||
if (cachedImage) {
|
||||
if (success) {
|
||||
success(urlRequest, nil, cachedImage);
|
||||
} else {
|
||||
[self setImage:cachedImage forState:state];
|
||||
}
|
||||
|
||||
[self af_setImageRequestOperation:nil forState:state];
|
||||
[self af_setImageDownloadReceipt:nil forState:state];
|
||||
} else {
|
||||
if (placeholderImage) {
|
||||
[self setImage:placeholderImage forState:state];
|
||||
}
|
||||
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
AFHTTPRequestOperation *imageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
|
||||
imageRequestOperation.responseSerializer = self.imageResponseSerializer;
|
||||
[imageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[urlRequest URL] isEqual:[operation.request URL]]) {
|
||||
if (success) {
|
||||
success(operation.request, operation.response, responseObject);
|
||||
} else if (responseObject) {
|
||||
[strongSelf setImage:responseObject forState:state];
|
||||
}
|
||||
}
|
||||
[[[strongSelf class] sharedImageCache] cacheImage:responseObject forRequest:urlRequest];
|
||||
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
||||
if ([[urlRequest URL] isEqual:[operation.request URL]]) {
|
||||
if (failure) {
|
||||
failure(error);
|
||||
}
|
||||
}
|
||||
}];
|
||||
NSUUID *downloadID = [NSUUID UUID];
|
||||
AFImageDownloadReceipt *receipt;
|
||||
receipt = [downloader
|
||||
downloadImageForURLRequest:urlRequest
|
||||
withReceiptID:downloadID
|
||||
success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull responseObject) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[strongSelf af_imageDownloadReceiptForState:state].receiptID isEqual:downloadID]) {
|
||||
if (success) {
|
||||
success(request, response, responseObject);
|
||||
} else if(responseObject) {
|
||||
[strongSelf setImage:responseObject forState:state];
|
||||
}
|
||||
[strongSelf af_setImageDownloadReceipt:nil forState:state];
|
||||
}
|
||||
|
||||
[self af_setImageRequestOperation:imageRequestOperation forState:state];
|
||||
[[[self class] af_sharedImageRequestOperationQueue] addOperation:imageRequestOperation];
|
||||
}
|
||||
failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[strongSelf af_imageDownloadReceiptForState:state].receiptID isEqual:downloadID]) {
|
||||
if (failure) {
|
||||
failure(request, response, error);
|
||||
}
|
||||
[strongSelf af_setImageDownloadReceipt:nil forState:state];
|
||||
}
|
||||
}];
|
||||
|
||||
[self af_setImageDownloadReceipt:receipt forState:state];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +202,7 @@ static const char * af_backgroundImageRequestOperationKeyForState(UIControlState
|
||||
|
||||
- (void)setBackgroundImageForState:(UIControlState)state
|
||||
withURL:(NSURL *)url
|
||||
placeholderImage:(UIImage *)placeholderImage
|
||||
placeholderImage:(nullable UIImage *)placeholderImage
|
||||
{
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
||||
[request addValue:@"image/*" forHTTPHeaderField:@"Accept"];
|
||||
@@ -230,64 +212,94 @@ static const char * af_backgroundImageRequestOperationKeyForState(UIControlState
|
||||
|
||||
- (void)setBackgroundImageForState:(UIControlState)state
|
||||
withURLRequest:(NSURLRequest *)urlRequest
|
||||
placeholderImage:(UIImage *)placeholderImage
|
||||
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
|
||||
failure:(void (^)(NSError *error))failure
|
||||
placeholderImage:(nullable UIImage *)placeholderImage
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure
|
||||
{
|
||||
[self cancelBackgroundImageRequestOperationForState:state];
|
||||
if ([self isActiveBackgroundTaskURLEqualToURLRequest:urlRequest forState:state]) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIImage *cachedImage = [[[self class] sharedImageCache] cachedImageForRequest:urlRequest];
|
||||
[self cancelBackgroundImageDownloadTaskForState:state];
|
||||
|
||||
AFImageDownloader *downloader = [[self class] sharedImageDownloader];
|
||||
id <AFImageRequestCache> imageCache = downloader.imageCache;
|
||||
|
||||
//Use the image from the image cache if it exists
|
||||
UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
|
||||
if (cachedImage) {
|
||||
if (success) {
|
||||
success(urlRequest, nil, cachedImage);
|
||||
} else {
|
||||
[self setBackgroundImage:cachedImage forState:state];
|
||||
}
|
||||
|
||||
[self af_setBackgroundImageRequestOperation:nil forState:state];
|
||||
[self af_setBackgroundImageDownloadReceipt:nil forState:state];
|
||||
} else {
|
||||
if (placeholderImage) {
|
||||
[self setBackgroundImage:placeholderImage forState:state];
|
||||
}
|
||||
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
AFHTTPRequestOperation *backgroundImageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
|
||||
backgroundImageRequestOperation.responseSerializer = self.imageResponseSerializer;
|
||||
[backgroundImageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[urlRequest URL] isEqual:[operation.request URL]]) {
|
||||
if (success) {
|
||||
success(operation.request, operation.response, responseObject);
|
||||
} else if (responseObject) {
|
||||
[strongSelf setBackgroundImage:responseObject forState:state];
|
||||
}
|
||||
}
|
||||
[[[strongSelf class] sharedImageCache] cacheImage:responseObject forRequest:urlRequest];
|
||||
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
||||
if ([[urlRequest URL] isEqual:[operation.request URL]]) {
|
||||
if (failure) {
|
||||
failure(error);
|
||||
}
|
||||
}
|
||||
}];
|
||||
NSUUID *downloadID = [NSUUID UUID];
|
||||
AFImageDownloadReceipt *receipt;
|
||||
receipt = [downloader
|
||||
downloadImageForURLRequest:urlRequest
|
||||
withReceiptID:downloadID
|
||||
success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull responseObject) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[strongSelf af_backgroundImageDownloadReceiptForState:state].receiptID isEqual:downloadID]) {
|
||||
if (success) {
|
||||
success(request, response, responseObject);
|
||||
} else if(responseObject) {
|
||||
[strongSelf setBackgroundImage:responseObject forState:state];
|
||||
}
|
||||
[strongSelf af_setBackgroundImageDownloadReceipt:nil forState:state];
|
||||
}
|
||||
|
||||
[self af_setBackgroundImageRequestOperation:backgroundImageRequestOperation forState:state];
|
||||
[[[self class] af_sharedImageRequestOperationQueue] addOperation:backgroundImageRequestOperation];
|
||||
}
|
||||
failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[strongSelf af_backgroundImageDownloadReceiptForState:state].receiptID isEqual:downloadID]) {
|
||||
if (failure) {
|
||||
failure(request, response, error);
|
||||
}
|
||||
[strongSelf af_setBackgroundImageDownloadReceipt:nil forState:state];
|
||||
}
|
||||
}];
|
||||
|
||||
[self af_setBackgroundImageDownloadReceipt:receipt forState:state];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)cancelImageRequestOperationForState:(UIControlState)state {
|
||||
[[self af_imageRequestOperationForState:state] cancel];
|
||||
[self af_setImageRequestOperation:nil forState:state];
|
||||
- (void)cancelImageDownloadTaskForState:(UIControlState)state {
|
||||
AFImageDownloadReceipt *receipt = [self af_imageDownloadReceiptForState:state];
|
||||
if (receipt != nil) {
|
||||
[[self.class sharedImageDownloader] cancelTaskForImageDownloadReceipt:receipt];
|
||||
[self af_setImageDownloadReceipt:nil forState:state];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelBackgroundImageRequestOperationForState:(UIControlState)state {
|
||||
[[self af_backgroundImageRequestOperationForState:state] cancel];
|
||||
[self af_setBackgroundImageRequestOperation:nil forState:state];
|
||||
- (void)cancelBackgroundImageDownloadTaskForState:(UIControlState)state {
|
||||
AFImageDownloadReceipt *receipt = [self af_backgroundImageDownloadReceiptForState:state];
|
||||
if (receipt != nil) {
|
||||
[[self.class sharedImageDownloader] cancelTaskForImageDownloadReceipt:receipt];
|
||||
[self af_setBackgroundImageDownloadReceipt:nil forState:state];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isActiveTaskURLEqualToURLRequest:(NSURLRequest *)urlRequest forState:(UIControlState)state {
|
||||
AFImageDownloadReceipt *receipt = [self af_imageDownloadReceiptForState:state];
|
||||
return [receipt.task.originalRequest.URL.absoluteString isEqualToString:urlRequest.URL.absoluteString];
|
||||
}
|
||||
|
||||
- (BOOL)isActiveBackgroundTaskURLEqualToURLRequest:(NSURLRequest *)urlRequest forState:(UIControlState)state {
|
||||
AFImageDownloadReceipt *receipt = [self af_backgroundImageDownloadReceiptForState:state];
|
||||
return [receipt.task.originalRequest.URL.absoluteString isEqualToString:urlRequest.URL.absoluteString];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
Regular → Executable
+1
-1
@@ -22,7 +22,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
Regular → Executable
+18
-55
@@ -1,5 +1,5 @@
|
||||
// UIImageView+AFNetworking.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,47 +21,36 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol AFURLResponseSerialization, AFImageCache;
|
||||
@class AFImageDownloader;
|
||||
|
||||
/**
|
||||
This category adds methods to the UIKit framework's `UIImageView` class. The methods in this category provide support for loading remote images asynchronously from a URL.
|
||||
*/
|
||||
@interface UIImageView (AFNetworking)
|
||||
|
||||
///----------------------------
|
||||
/// @name Accessing Image Cache
|
||||
///----------------------------
|
||||
|
||||
/**
|
||||
The image cache used to improve image loading performance on scroll views. By default, this is an `NSCache` subclass conforming to the `AFImageCache` protocol, which listens for notification warnings and evicts objects accordingly.
|
||||
*/
|
||||
+ (id <AFImageCache>)sharedImageCache;
|
||||
|
||||
/**
|
||||
Set the cache used for image loading.
|
||||
|
||||
@param imageCache The image cache.
|
||||
*/
|
||||
+ (void)setSharedImageCache:(__nullable id <AFImageCache>)imageCache;
|
||||
|
||||
///------------------------------------
|
||||
/// @name Accessing Response Serializer
|
||||
/// @name Accessing the Image Downloader
|
||||
///------------------------------------
|
||||
|
||||
/**
|
||||
The response serializer used to create an image representation from the server response and response data. By default, this is an instance of `AFImageResponseSerializer`.
|
||||
Set the shared image downloader used to download images.
|
||||
|
||||
@discussion Subclasses of `AFImageResponseSerializer` could be used to perform post-processing, such as color correction, face detection, or other effects. See https://github.com/AFNetworking/AFCoreImageSerializer
|
||||
@param imageDownloader The shared image downloader used to download images.
|
||||
*/
|
||||
@property (nonatomic, strong) id <AFURLResponseSerialization> imageResponseSerializer;
|
||||
+ (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader;
|
||||
|
||||
/**
|
||||
The shared image downloader used to download images.
|
||||
*/
|
||||
+ (AFImageDownloader *)sharedImageDownloader;
|
||||
|
||||
///--------------------
|
||||
/// @name Setting Image
|
||||
@@ -100,47 +89,21 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@param urlRequest The URL request used for the image request.
|
||||
@param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes.
|
||||
@param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
|
||||
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
|
||||
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
|
||||
*/
|
||||
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
|
||||
placeholderImage:(nullable UIImage *)placeholderImage
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, NSError *error))failure;
|
||||
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
|
||||
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
|
||||
|
||||
/**
|
||||
Cancels any executing image operation for the receiver, if one exists.
|
||||
*/
|
||||
- (void)cancelImageRequestOperation;
|
||||
- (void)cancelImageDownloadTask;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/**
|
||||
The `AFImageCache` protocol is adopted by an object used to cache images loaded by the AFNetworking category on `UIImageView`.
|
||||
*/
|
||||
@protocol AFImageCache <NSObject>
|
||||
|
||||
/**
|
||||
Returns a cached image for the specified request, if available.
|
||||
|
||||
@param request The image request.
|
||||
|
||||
@return The cached image.
|
||||
*/
|
||||
- (nullable UIImage *)cachedImageForRequest:(NSURLRequest *)request;
|
||||
|
||||
/**
|
||||
Caches a particular image for the specified request.
|
||||
|
||||
@param image The image to cache.
|
||||
@param request The request to be used as a cache key.
|
||||
*/
|
||||
- (void)cacheImage:(UIImage *)image
|
||||
forRequest:(NSURLRequest *)request;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
|
||||
Regular → Executable
+67
-121
@@ -1,5 +1,5 @@
|
||||
// UIImageView+AFNetworking.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,38 +23,22 @@
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
|
||||
@interface AFImageCache : NSCache <AFImageCache>
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
#import "AFImageDownloader.h"
|
||||
|
||||
@interface UIImageView (_AFNetworking)
|
||||
@property (readwrite, nonatomic, strong, setter = af_setImageRequestOperation:) AFHTTPRequestOperation *af_imageRequestOperation;
|
||||
@property (readwrite, nonatomic, strong, setter = af_setActiveImageDownloadReceipt:) AFImageDownloadReceipt *af_activeImageDownloadReceipt;
|
||||
@end
|
||||
|
||||
@implementation UIImageView (_AFNetworking)
|
||||
|
||||
+ (NSOperationQueue *)af_sharedImageRequestOperationQueue {
|
||||
static NSOperationQueue *_af_sharedImageRequestOperationQueue = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_af_sharedImageRequestOperationQueue = [[NSOperationQueue alloc] init];
|
||||
_af_sharedImageRequestOperationQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
|
||||
});
|
||||
|
||||
return _af_sharedImageRequestOperationQueue;
|
||||
- (AFImageDownloadReceipt *)af_activeImageDownloadReceipt {
|
||||
return (AFImageDownloadReceipt *)objc_getAssociatedObject(self, @selector(af_activeImageDownloadReceipt));
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)af_imageRequestOperation {
|
||||
return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, @selector(af_imageRequestOperation));
|
||||
}
|
||||
|
||||
- (void)af_setImageRequestOperation:(AFHTTPRequestOperation *)imageRequestOperation {
|
||||
objc_setAssociatedObject(self, @selector(af_imageRequestOperation), imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
- (void)af_setActiveImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt {
|
||||
objc_setAssociatedObject(self, @selector(af_activeImageDownloadReceipt), imageDownloadReceipt, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -62,46 +46,17 @@
|
||||
#pragma mark -
|
||||
|
||||
@implementation UIImageView (AFNetworking)
|
||||
@dynamic imageResponseSerializer;
|
||||
|
||||
+ (id <AFImageCache>)sharedImageCache {
|
||||
static AFImageCache *_af_defaultImageCache = nil;
|
||||
static dispatch_once_t oncePredicate;
|
||||
dispatch_once(&oncePredicate, ^{
|
||||
_af_defaultImageCache = [[AFImageCache alloc] init];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * __unused notification) {
|
||||
[_af_defaultImageCache removeAllObjects];
|
||||
}];
|
||||
});
|
||||
+ (AFImageDownloader *)sharedImageDownloader {
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
return objc_getAssociatedObject(self, @selector(sharedImageCache)) ?: _af_defaultImageCache;
|
||||
return objc_getAssociatedObject(self, @selector(sharedImageDownloader)) ?: [AFImageDownloader defaultInstance];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
+ (void)setSharedImageCache:(__nullable id <AFImageCache>)imageCache {
|
||||
objc_setAssociatedObject(self, @selector(sharedImageCache), imageCache, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (id <AFURLResponseSerialization>)imageResponseSerializer {
|
||||
static id <AFURLResponseSerialization> _af_defaultImageResponseSerializer = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_af_defaultImageResponseSerializer = [AFImageResponseSerializer serializer];
|
||||
});
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
return objc_getAssociatedObject(self, @selector(imageResponseSerializer)) ?: _af_defaultImageResponseSerializer;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
- (void)setImageResponseSerializer:(id <AFURLResponseSerialization>)serializer {
|
||||
objc_setAssociatedObject(self, @selector(imageResponseSerializer), serializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
+ (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader {
|
||||
objc_setAssociatedObject(self, @selector(sharedImageDownloader), imageDownloader, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -121,93 +76,84 @@
|
||||
|
||||
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
|
||||
placeholderImage:(UIImage *)placeholderImage
|
||||
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
|
||||
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, NSError *error))failure
|
||||
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
|
||||
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure
|
||||
{
|
||||
[self cancelImageRequestOperation];
|
||||
|
||||
UIImage *cachedImage = [[[self class] sharedImageCache] cachedImageForRequest:urlRequest];
|
||||
if ([urlRequest URL] == nil) {
|
||||
[self cancelImageDownloadTask];
|
||||
self.image = placeholderImage;
|
||||
return;
|
||||
}
|
||||
|
||||
if ([self isActiveTaskURLEqualToURLRequest:urlRequest]){
|
||||
return;
|
||||
}
|
||||
|
||||
[self cancelImageDownloadTask];
|
||||
|
||||
AFImageDownloader *downloader = [[self class] sharedImageDownloader];
|
||||
id <AFImageRequestCache> imageCache = downloader.imageCache;
|
||||
|
||||
//Use the image from the image cache if it exists
|
||||
UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
|
||||
if (cachedImage) {
|
||||
if (success) {
|
||||
success(urlRequest, nil, cachedImage);
|
||||
} else {
|
||||
self.image = cachedImage;
|
||||
}
|
||||
|
||||
self.af_imageRequestOperation = nil;
|
||||
[self clearActiveDownloadInformation];
|
||||
} else {
|
||||
if (placeholderImage) {
|
||||
self.image = placeholderImage;
|
||||
}
|
||||
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
self.af_imageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
|
||||
self.af_imageRequestOperation.responseSerializer = self.imageResponseSerializer;
|
||||
[self.af_imageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[urlRequest URL] isEqual:[strongSelf.af_imageRequestOperation.request URL]]) {
|
||||
if (success) {
|
||||
success(urlRequest, operation.response, responseObject);
|
||||
} else if (responseObject) {
|
||||
strongSelf.image = responseObject;
|
||||
}
|
||||
NSUUID *downloadID = [NSUUID UUID];
|
||||
AFImageDownloadReceipt *receipt;
|
||||
receipt = [downloader
|
||||
downloadImageForURLRequest:urlRequest
|
||||
withReceiptID:downloadID
|
||||
success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull responseObject) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([strongSelf.af_activeImageDownloadReceipt.receiptID isEqual:downloadID]) {
|
||||
if (success) {
|
||||
success(request, response, responseObject);
|
||||
} else if(responseObject) {
|
||||
strongSelf.image = responseObject;
|
||||
}
|
||||
[strongSelf clearActiveDownloadInformation];
|
||||
}
|
||||
|
||||
if (operation == strongSelf.af_imageRequestOperation){
|
||||
strongSelf.af_imageRequestOperation = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([strongSelf.af_activeImageDownloadReceipt.receiptID isEqual:downloadID]) {
|
||||
if (failure) {
|
||||
failure(request, response, error);
|
||||
}
|
||||
[strongSelf clearActiveDownloadInformation];
|
||||
}
|
||||
}];
|
||||
|
||||
[[[strongSelf class] sharedImageCache] cacheImage:responseObject forRequest:urlRequest];
|
||||
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if ([[urlRequest URL] isEqual:[strongSelf.af_imageRequestOperation.request URL]]) {
|
||||
if (failure) {
|
||||
failure(urlRequest, operation.response, error);
|
||||
}
|
||||
|
||||
if (operation == strongSelf.af_imageRequestOperation){
|
||||
strongSelf.af_imageRequestOperation = nil;
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
[[[self class] af_sharedImageRequestOperationQueue] addOperation:self.af_imageRequestOperation];
|
||||
self.af_activeImageDownloadReceipt = receipt;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelImageRequestOperation {
|
||||
[self.af_imageRequestOperation cancel];
|
||||
self.af_imageRequestOperation = nil;
|
||||
- (void)cancelImageDownloadTask {
|
||||
if (self.af_activeImageDownloadReceipt != nil) {
|
||||
[[self.class sharedImageDownloader] cancelTaskForImageDownloadReceipt:self.af_activeImageDownloadReceipt];
|
||||
[self clearActiveDownloadInformation];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static inline NSString * AFImageCacheKeyFromURLRequest(NSURLRequest *request) {
|
||||
return [[request URL] absoluteString];
|
||||
- (void)clearActiveDownloadInformation {
|
||||
self.af_activeImageDownloadReceipt = nil;
|
||||
}
|
||||
|
||||
@implementation AFImageCache
|
||||
|
||||
- (UIImage *)cachedImageForRequest:(NSURLRequest *)request {
|
||||
switch ([request cachePolicy]) {
|
||||
case NSURLRequestReloadIgnoringCacheData:
|
||||
case NSURLRequestReloadIgnoringLocalAndRemoteCacheData:
|
||||
return nil;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return [self objectForKey:AFImageCacheKeyFromURLRequest(request)];
|
||||
}
|
||||
|
||||
- (void)cacheImage:(UIImage *)image
|
||||
forRequest:(NSURLRequest *)request
|
||||
{
|
||||
if (image && request) {
|
||||
[self setObject:image forKey:AFImageCacheKeyFromURLRequest(request)];
|
||||
}
|
||||
- (BOOL)isActiveTaskURLEqualToURLRequest:(NSURLRequest *)urlRequest {
|
||||
return [self.af_activeImageDownloadReceipt.task.originalRequest.URL.absoluteString isEqualToString:urlRequest.URL.absoluteString];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Regular → Executable
+8
-5
@@ -1,6 +1,6 @@
|
||||
// UIKit+AFNetworking.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,20 +20,23 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#ifndef _UIKIT_AFNETWORKING_
|
||||
#define _UIKIT_AFNETWORKING_
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import "AFAutoPurgingImageCache.h"
|
||||
#import "AFImageDownloader.h"
|
||||
#import "AFNetworkActivityIndicatorManager.h"
|
||||
#import "UIRefreshControl+AFNetworking.h"
|
||||
#import "UIWebView+AFNetworking.h"
|
||||
#endif
|
||||
|
||||
#import "UIActivityIndicatorView+AFNetworking.h"
|
||||
#import "UIAlertView+AFNetworking.h"
|
||||
#import "UIButton+AFNetworking.h"
|
||||
#import "UIImageView+AFNetworking.h"
|
||||
#import "UIProgressView+AFNetworking.h"
|
||||
#import "UIRefreshControl+AFNetworking.h"
|
||||
#import "UIWebView+AFNetworking.h"
|
||||
#endif /* _UIKIT_AFNETWORKING_ */
|
||||
#endif
|
||||
|
||||
Regular → Executable
+4
-31
@@ -1,5 +1,5 @@
|
||||
// UIProgressView+AFNetworking.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,18 +21,17 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class AFURLConnectionOperation;
|
||||
|
||||
/**
|
||||
This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task or request operation.
|
||||
This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task.
|
||||
*/
|
||||
@interface UIProgressView (AFNetworking)
|
||||
|
||||
@@ -46,10 +45,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@param task The session task.
|
||||
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task
|
||||
animated:(BOOL)animated;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Binds the progress to the download progress of the specified session task.
|
||||
@@ -57,32 +54,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@param task The session task.
|
||||
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task
|
||||
animated:(BOOL)animated;
|
||||
#endif
|
||||
|
||||
///------------------------------------
|
||||
/// @name Setting Session Task Progress
|
||||
///------------------------------------
|
||||
|
||||
/**
|
||||
Binds the progress to the upload progress of the specified request operation.
|
||||
|
||||
@param operation The request operation.
|
||||
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
|
||||
*/
|
||||
- (void)setProgressWithUploadProgressOfOperation:(AFURLConnectionOperation *)operation
|
||||
animated:(BOOL)animated;
|
||||
|
||||
/**
|
||||
Binds the progress to the download progress of the specified request operation.
|
||||
|
||||
@param operation The request operation.
|
||||
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
|
||||
*/
|
||||
- (void)setProgressWithDownloadProgressOfOperation:(AFURLConnectionOperation *)operation
|
||||
animated:(BOOL)animated;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
Regular → Executable
+2
-66
@@ -1,5 +1,5 @@
|
||||
// UIProgressView+AFNetworking.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,33 +23,13 @@
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
#import "AFURLConnectionOperation.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
#import "AFURLSessionManager.h"
|
||||
#endif
|
||||
|
||||
static void * AFTaskCountOfBytesSentContext = &AFTaskCountOfBytesSentContext;
|
||||
static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedContext;
|
||||
|
||||
@interface AFURLConnectionOperation (_UIProgressView)
|
||||
@property (readwrite, nonatomic, copy) void (^uploadProgress)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected);
|
||||
@property (readwrite, nonatomic, assign, setter = af_setUploadProgressAnimated:) BOOL af_uploadProgressAnimated;
|
||||
|
||||
@property (readwrite, nonatomic, copy) void (^downloadProgress)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected);
|
||||
@property (readwrite, nonatomic, assign, setter = af_setDownloadProgressAnimated:) BOOL af_downloadProgressAnimated;
|
||||
@end
|
||||
|
||||
@implementation AFURLConnectionOperation (_UIProgressView)
|
||||
@dynamic uploadProgress; // Implemented in AFURLConnectionOperation
|
||||
@dynamic af_uploadProgressAnimated;
|
||||
|
||||
@dynamic downloadProgress; // Implemented in AFURLConnectionOperation
|
||||
@dynamic af_downloadProgressAnimated;
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation UIProgressView (AFNetworking)
|
||||
@@ -72,7 +52,6 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task
|
||||
animated:(BOOL)animated
|
||||
{
|
||||
@@ -90,47 +69,6 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
|
||||
|
||||
[self af_setDownloadProgressAnimated:animated];
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setProgressWithUploadProgressOfOperation:(AFURLConnectionOperation *)operation
|
||||
animated:(BOOL)animated
|
||||
{
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
void (^original)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) = [operation.uploadProgress copy];
|
||||
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
|
||||
if (original) {
|
||||
original(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (totalBytesExpectedToWrite > 0) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf setProgress:(totalBytesWritten / (totalBytesExpectedToWrite * 1.0f)) animated:animated];
|
||||
}
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setProgressWithDownloadProgressOfOperation:(AFURLConnectionOperation *)operation
|
||||
animated:(BOOL)animated
|
||||
{
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
void (^original)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) = [operation.downloadProgress copy];
|
||||
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
|
||||
if (original) {
|
||||
original(bytesRead, totalBytesRead, totalBytesExpectedToRead);
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (totalBytesExpectedToRead > 0) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf setProgress:(totalBytesRead / (totalBytesExpectedToRead * 1.0f)) animated:animated];
|
||||
}
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - NSKeyValueObserving
|
||||
|
||||
@@ -139,7 +77,6 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
|
||||
change:(__unused NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
if (context == AFTaskCountOfBytesSentContext || context == AFTaskCountOfBytesReceivedContext) {
|
||||
if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) {
|
||||
if ([object countOfBytesExpectedToSend] > 0) {
|
||||
@@ -174,7 +111,6 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Regular → Executable
+4
-19
@@ -1,6 +1,6 @@
|
||||
// UIRefreshControl+AFNetworking.m
|
||||
//
|
||||
// Copyright (c) 2014 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,18 +22,16 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class AFURLConnectionOperation;
|
||||
|
||||
/**
|
||||
This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a request operation or session task.
|
||||
This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a session task.
|
||||
*/
|
||||
@interface UIRefreshControl (AFNetworking)
|
||||
|
||||
@@ -46,20 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
|
||||
#endif
|
||||
|
||||
///----------------------------------------
|
||||
/// @name Refreshing for Request Operations
|
||||
///----------------------------------------
|
||||
|
||||
/**
|
||||
Binds the refreshing state to the execution state of the specified operation.
|
||||
|
||||
@param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled.
|
||||
*/
|
||||
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
Regular → Executable
+2
-46
@@ -1,6 +1,6 @@
|
||||
// UIRefreshControl+AFNetworking.m
|
||||
//
|
||||
// Copyright (c) 2014 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,22 +23,15 @@
|
||||
#import "UIRefreshControl+AFNetworking.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
#import "AFURLSessionManager.h"
|
||||
#endif
|
||||
|
||||
@interface AFRefreshControlNotificationObserver : NSObject
|
||||
@property (readonly, nonatomic, weak) UIRefreshControl *refreshControl;
|
||||
- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl;
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
|
||||
#endif
|
||||
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation;
|
||||
|
||||
@end
|
||||
|
||||
@@ -53,15 +46,9 @@
|
||||
return notificationObserver;
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
|
||||
[[self af_notificationObserver] setRefreshingWithStateOfTask:task];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation {
|
||||
[[self af_notificationObserver] setRefreshingWithStateOfOperation:operation];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -76,7 +63,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
@@ -100,31 +86,6 @@
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
|
||||
|
||||
if (operation) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
|
||||
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
|
||||
if (![operation isFinished]) {
|
||||
if ([operation isExecuting]) {
|
||||
[self.refreshControl beginRefreshing];
|
||||
} else {
|
||||
[self.refreshControl endRefreshing];
|
||||
}
|
||||
|
||||
[notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingOperationDidStartNotification object:operation];
|
||||
[notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingOperationDidFinishNotification object:operation];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@@ -151,14 +112,9 @@
|
||||
- (void)dealloc {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
|
||||
[notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
|
||||
#endif
|
||||
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
|
||||
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Regular → Executable
+12
-18
@@ -1,5 +1,5 @@
|
||||
// UIWebView+AFNetworking.h
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,16 +21,15 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class AFHTTPRequestSerializer, AFHTTPResponseSerializer;
|
||||
@protocol AFURLRequestSerialization, AFURLResponseSerialization;
|
||||
@class AFHTTPSessionManager;
|
||||
|
||||
/**
|
||||
This category adds methods to the UIKit framework's `UIWebView` class. The methods in this category provide increased control over the request cycle, including progress monitoring and success / failure handling.
|
||||
@@ -40,25 +39,20 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@interface UIWebView (AFNetworking)
|
||||
|
||||
/**
|
||||
The request serializer used to serialize requests made with the `-loadRequest:...` category methods. By default, this is an instance of `AFHTTPRequestSerializer`.
|
||||
The session manager used to download all requests.
|
||||
*/
|
||||
@property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer;
|
||||
|
||||
/**
|
||||
The response serializer used to serialize responses made with the `-loadRequest:...` category methods. By default, this is an instance of `AFHTTPResponseSerializer`.
|
||||
*/
|
||||
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;
|
||||
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;
|
||||
|
||||
/**
|
||||
Asynchronously loads the specified request.
|
||||
|
||||
@param request A URL request identifying the location of the content to load. This must not be `nil`.
|
||||
@param progress A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread.
|
||||
@param progress A progress object monitoring the current download progress.
|
||||
@param success A block object to be executed when the request finishes loading successfully. This block returns the HTML string to be loaded by the web view, and takes two arguments: the response, and the response string.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
|
||||
@param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
|
||||
*/
|
||||
- (void)loadRequest:(NSURLRequest *)request
|
||||
progress:(nullable void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
|
||||
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
|
||||
success:(nullable NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success
|
||||
failure:(nullable void (^)(NSError *error))failure;
|
||||
|
||||
@@ -68,14 +62,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@param request A URL request identifying the location of the content to load. This must not be `nil`.
|
||||
@param MIMEType The MIME type of the content. Defaults to the content type of the response if not specified.
|
||||
@param textEncodingName The IANA encoding name, as in `utf-8` or `utf-16`. Defaults to the response text encoding if not specified.
|
||||
@param progress A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread.
|
||||
@param progress A progress object monitoring the current download progress.
|
||||
@param success A block object to be executed when the request finishes loading successfully. This block returns the data to be loaded by the web view and takes two arguments: the response, and the downloaded data.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
|
||||
@param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
|
||||
*/
|
||||
- (void)loadRequest:(NSURLRequest *)request
|
||||
MIMEType:(nullable NSString *)MIMEType
|
||||
textEncodingName:(nullable NSString *)textEncodingName
|
||||
progress:(nullable void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
|
||||
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
|
||||
success:(nullable NSData * (^)(NSHTTPURLResponse *response, NSData *data))success
|
||||
failure:(nullable void (^)(NSError *error))failure;
|
||||
|
||||
|
||||
Regular → Executable
+47
-44
@@ -1,5 +1,5 @@
|
||||
// UIWebView+AFNetworking.m
|
||||
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
|
||||
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,24 +23,24 @@
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
#import "AFHTTPSessionManager.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
#import "AFURLRequestSerialization.h"
|
||||
|
||||
@interface UIWebView (_AFNetworking)
|
||||
@property (readwrite, nonatomic, strong, setter = af_setHTTPRequestOperation:) AFHTTPRequestOperation *af_HTTPRequestOperation;
|
||||
@property (readwrite, nonatomic, strong, setter = af_setURLSessionTask:) NSURLSessionDataTask *af_URLSessionTask;
|
||||
@end
|
||||
|
||||
@implementation UIWebView (_AFNetworking)
|
||||
|
||||
- (AFHTTPRequestOperation *)af_HTTPRequestOperation {
|
||||
return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, @selector(af_HTTPRequestOperation));
|
||||
- (NSURLSessionDataTask *)af_URLSessionTask {
|
||||
return (NSURLSessionDataTask *)objc_getAssociatedObject(self, @selector(af_URLSessionTask));
|
||||
}
|
||||
|
||||
- (void)af_setHTTPRequestOperation:(AFHTTPRequestOperation *)operation {
|
||||
objc_setAssociatedObject(self, @selector(af_HTTPRequestOperation), operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
- (void)af_setURLSessionTask:(NSURLSessionDataTask *)af_URLSessionTask {
|
||||
objc_setAssociatedObject(self, @selector(af_URLSessionTask), af_URLSessionTask, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -49,21 +49,23 @@
|
||||
|
||||
@implementation UIWebView (AFNetworking)
|
||||
|
||||
- (AFHTTPRequestSerializer <AFURLRequestSerialization> *)requestSerializer {
|
||||
static AFHTTPRequestSerializer <AFURLRequestSerialization> *_af_defaultRequestSerializer = nil;
|
||||
- (AFHTTPSessionManager *)sessionManager {
|
||||
static AFHTTPSessionManager *_af_defaultHTTPSessionManager = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_af_defaultRequestSerializer = [AFHTTPRequestSerializer serializer];
|
||||
_af_defaultHTTPSessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
|
||||
_af_defaultHTTPSessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
|
||||
_af_defaultHTTPSessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
});
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
return objc_getAssociatedObject(self, @selector(requestSerializer)) ?: _af_defaultRequestSerializer;
|
||||
return objc_getAssociatedObject(self, @selector(sessionManager)) ?: _af_defaultHTTPSessionManager;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
- (void)setRequestSerializer:(AFHTTPRequestSerializer<AFURLRequestSerialization> *)requestSerializer {
|
||||
objc_setAssociatedObject(self, @selector(requestSerializer), requestSerializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
- (void)setSessionManager:(AFHTTPSessionManager *)sessionManager {
|
||||
objc_setAssociatedObject(self, @selector(sessionManager), sessionManager, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer {
|
||||
@@ -86,7 +88,7 @@
|
||||
#pragma mark -
|
||||
|
||||
- (void)loadRequest:(NSURLRequest *)request
|
||||
progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
|
||||
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
|
||||
success:(NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success
|
||||
failure:(void (^)(NSError *error))failure
|
||||
{
|
||||
@@ -111,43 +113,44 @@
|
||||
- (void)loadRequest:(NSURLRequest *)request
|
||||
MIMEType:(NSString *)MIMEType
|
||||
textEncodingName:(NSString *)textEncodingName
|
||||
progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
|
||||
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
|
||||
success:(NSData * (^)(NSHTTPURLResponse *response, NSData *data))success
|
||||
failure:(void (^)(NSError *error))failure
|
||||
{
|
||||
NSParameterAssert(request);
|
||||
|
||||
if (self.af_HTTPRequestOperation) {
|
||||
[self.af_HTTPRequestOperation cancel];
|
||||
if (self.af_URLSessionTask.state == NSURLSessionTaskStateRunning || self.af_URLSessionTask.state == NSURLSessionTaskStateSuspended) {
|
||||
[self.af_URLSessionTask cancel];
|
||||
}
|
||||
|
||||
request = [self.requestSerializer requestBySerializingRequest:request withParameters:nil error:nil];
|
||||
|
||||
self.af_HTTPRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
|
||||
self.af_HTTPRequestOperation.responseSerializer = self.responseSerializer;
|
||||
self.af_URLSessionTask = nil;
|
||||
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
[self.af_HTTPRequestOperation setDownloadProgressBlock:progress];
|
||||
[self.af_HTTPRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id __unused responseObject) {
|
||||
NSData *data = success ? success(operation.response, operation.responseData) : operation.responseData;
|
||||
NSURLSessionDataTask *dataTask;
|
||||
dataTask = [self.sessionManager
|
||||
GET:request.URL.absoluteString
|
||||
parameters:nil
|
||||
progress:nil
|
||||
success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) {
|
||||
__strong __typeof(weakSelf) strongSelf = weakSelf;
|
||||
if (success) {
|
||||
success((NSHTTPURLResponse *)task.response, responseObject);
|
||||
}
|
||||
[strongSelf loadData:responseObject MIMEType:MIMEType textEncodingName:textEncodingName baseURL:[task.currentRequest URL]];
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
__strong __typeof(weakSelf) strongSelf = weakSelf;
|
||||
[strongSelf loadData:data MIMEType:(MIMEType ?: [operation.response MIMEType]) textEncodingName:(textEncodingName ?: [operation.response textEncodingName]) baseURL:[operation.response URL]];
|
||||
|
||||
if ([strongSelf.delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
|
||||
[strongSelf.delegate webViewDidFinishLoad:strongSelf];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
} failure:^(AFHTTPRequestOperation * __unused operation, NSError *error) {
|
||||
if (failure) {
|
||||
failure(error);
|
||||
}
|
||||
}];
|
||||
|
||||
[self.af_HTTPRequestOperation start];
|
||||
if ([strongSelf.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
|
||||
[strongSelf.delegate webViewDidFinishLoad:strongSelf];
|
||||
}
|
||||
}
|
||||
failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
|
||||
if (failure) {
|
||||
failure(error);
|
||||
}
|
||||
}];
|
||||
self.af_URLSessionTask = dataTask;
|
||||
if (progress != nil) {
|
||||
*progress = [self.sessionManager downloadProgressForTask:dataTask];
|
||||
}
|
||||
[self.af_URLSessionTask resume];
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
|
||||
[self.delegate webViewDidStartLoad:self];
|
||||
@@ -156,4 +159,4 @@
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -41,12 +41,12 @@ class SignUpRequestManager: NSObject {
|
||||
}
|
||||
|
||||
let baseURLString: String
|
||||
let manager: AFHTTPRequestOperationManager
|
||||
let manager: AFHTTPSessionManager
|
||||
let sessionManager: AFURLSessionManager
|
||||
|
||||
init(baseURLString: String = "") {
|
||||
self.baseURLString = baseURLString
|
||||
manager = AFHTTPRequestOperationManager(baseURL: URL(string: baseURLString))
|
||||
manager = AFHTTPSessionManager(baseURL: URL(string: baseURLString))
|
||||
manager.requestSerializer = AFJSONRequestSerializer() as AFHTTPRequestSerializer
|
||||
manager.requestSerializer.timeoutInterval = Application.RequestTimeout
|
||||
manager.responseSerializer = AFJSONResponseSerializer() as AFHTTPResponseSerializer
|
||||
@@ -65,7 +65,7 @@ class SignUpRequestManager: NSObject {
|
||||
{
|
||||
let urlString = "\(basePathString)/access_token"
|
||||
manager.requestSerializer.setAuthorizationHeaderFieldWithUsername(userName, password: password)
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postAccessTokenSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postAccessTokenFailure(error: error, failure: failure)
|
||||
@@ -113,7 +113,7 @@ class SignUpRequestManager: NSObject {
|
||||
failure: @escaping (_ error: Error, _ message: String?) -> Void)
|
||||
{
|
||||
if let urlString = "\(basePathString)/create_user?username=\(userName)&email=\(email)&fullName=\(fullName)&company=\(company)&password=\(password)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postCreateUserSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postCreateUserFailure(error: error, failure: failure)
|
||||
@@ -180,7 +180,7 @@ class SignUpRequestManager: NSObject {
|
||||
success: @escaping () -> Void,
|
||||
failure: @escaping (_ error: Error, _ message: String?) -> Void)
|
||||
{
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postForgotPasswordSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postForgotPasswordFailure(error: error, failure: failure)
|
||||
@@ -209,7 +209,7 @@ class SignUpRequestManager: NSObject {
|
||||
failure: @escaping (_ error: Error, _ message: String?) -> Void)
|
||||
{
|
||||
let urlString = "\(basePathString)/hello"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postHelloSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postHelloFailure(error: error, failure: failure)
|
||||
@@ -254,7 +254,7 @@ class SignUpRequestManager: NSObject {
|
||||
{
|
||||
let urlString = "\(basePathString)/logout/"
|
||||
manager.requestSerializer.clearAuthorizationHeader()
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postLogoutSuccess(success: success)
|
||||
}) { (requestOperation, error) in
|
||||
self.postLogoutFailure(error: error, failure: failure)
|
||||
|
||||
@@ -19,12 +19,12 @@ class TrainingRequestManager: NSObject {
|
||||
fileprivate let basePathString = "/sailingserver/api/v1"
|
||||
|
||||
let baseURLString: String
|
||||
let manager: AFHTTPRequestOperationManager
|
||||
let manager: AFHTTPSessionManager
|
||||
let sessionManager: AFURLSessionManager
|
||||
|
||||
init(baseURLString: String = "") {
|
||||
self.baseURLString = baseURLString
|
||||
manager = AFHTTPRequestOperationManager(baseURL: URL(string: baseURLString))
|
||||
manager = AFHTTPSessionManager(baseURL: URL(string: baseURLString))
|
||||
manager.requestSerializer = AFHTTPRequestSerializer()
|
||||
manager.requestSerializer.timeoutInterval = Application.RequestTimeout
|
||||
manager.responseSerializer = AFHTTPResponseSerializer()
|
||||
@@ -59,7 +59,7 @@ class TrainingRequestManager: NSObject {
|
||||
body["createregatta"] = "true" as AnyObject
|
||||
body["boatclassname"] = boatClassName as AnyObject
|
||||
body["numberofraces"] = "0" as AnyObject
|
||||
manager.post(urlString, parameters: body, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: body, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postCreateEventSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postCreateEventFailure(error: error, failure: failure)
|
||||
@@ -133,7 +133,7 @@ class TrainingRequestManager: NSObject {
|
||||
let encodedRegattaName = regattaName.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? ""
|
||||
let encodedCompetitorID = competitorID.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/regattas/\(encodedRegattaName)/competitors/\(encodedCompetitorID)/add"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postRegattaCompetitorAddSuccess(responseObject: responseObject, success: success)
|
||||
}) { (requestOperation, error) in
|
||||
self.postRegattaCompetitorAddFailure(error: error, failure: failure)
|
||||
@@ -165,7 +165,7 @@ class TrainingRequestManager: NSObject {
|
||||
let encodedSailID = sailID.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let encodedNationality = nationality.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/regattas/\(encodedRegattaName)/competitors/createandadd?boatclass=\(encodedBoatClassName)&sailid=\(encodedSailID)&nationalityIOC=\(encodedNationality)"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postRegattaCompetitorCreateAndAddSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postRegattaCompetitorCreateAndAddFailure(error: error, failure: failure)
|
||||
@@ -203,7 +203,7 @@ class TrainingRequestManager: NSObject {
|
||||
{
|
||||
let encodedRegattaName = regattaName.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/regattas/\(encodedRegattaName)/addracecolumns"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postRegattaRaceColumnAddSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postRegattaRaceColumnAddAddFailure(error: error, failure: failure)
|
||||
@@ -280,7 +280,7 @@ class TrainingRequestManager: NSObject {
|
||||
let encodedRaceColumnName = raceColumnName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let encodedFleetName = fleetName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/leaderboards/\(encodedLeaderboardName)/settrackingtimes?race_column=\(encodedRaceColumnName)&fleet=\(encodedFleetName)&\(millisParameter)=\(millisSince1970())"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postLeaderboardRaceSetTrackingTimeMillisSuccess(responseObject: responseObject, success: success)
|
||||
}) { (requestOperation, error) in
|
||||
self.postLeaderboardRaceSetTrackingTimeMillisFailure(error: error, failure: failure)
|
||||
@@ -310,7 +310,7 @@ class TrainingRequestManager: NSObject {
|
||||
let encodedRaceColumnName = raceColumnName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let encodedFleetName = fleetName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/leaderboards/\(encodedLeaderboardName)/starttracking?race_column=\(encodedRaceColumnName)&fleet=\(encodedFleetName)"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postLeaderboardStartTrackingSuccess(responseObject: responseObject, success: success)
|
||||
}) { (requestOperation, error) in
|
||||
self.postLeaderboardStartTrackingFailure(error: error, failure: failure)
|
||||
@@ -366,7 +366,7 @@ class TrainingRequestManager: NSObject {
|
||||
let encodedLeaderboardName = leaderboardName.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? ""
|
||||
let encodedQuery = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/leaderboards/\(encodedLeaderboardName)/stoptracking?\(encodedQuery)"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postLeaderboardStopTrackingSuccess(responseObject: responseObject, success: success)
|
||||
}) { (requestOperation, error) in
|
||||
self.postLeaderboardStopTrackingFailure(error: error, failure: failure)
|
||||
@@ -392,7 +392,7 @@ class TrainingRequestManager: NSObject {
|
||||
{
|
||||
let encodedLeaderboardName = leaderboardName.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/leaderboardgroups/\(encodedLeaderboardName)"
|
||||
manager.get(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.get(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.getLeaderboardGroupSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.getLeaderboardGroupFailure(error: error, failure: failure)
|
||||
@@ -432,7 +432,7 @@ class TrainingRequestManager: NSObject {
|
||||
let encodedRegattaName = regattaName.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? ""
|
||||
let encodedRaceName = raceName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/regattas/\(encodedRegattaName)/races/\(encodedRaceName)/course"
|
||||
manager.get(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.get(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.getRegattaRaceCourseSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.getRegattaRaceCourseFailure(error: error, failure: failure)
|
||||
@@ -474,7 +474,7 @@ class TrainingRequestManager: NSObject {
|
||||
let encodedRaceColumnName = raceColumnName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let encodedFleetName = fleetName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
|
||||
let urlString = "\(basePathString)/leaderboards/\(encodedLeaderboardName)/autocourse?race_column=\(encodedRaceColumnName)&fleet=\(encodedFleetName)"
|
||||
manager.post(urlString, parameters: nil, success: { (requestOperation, responseObject) in
|
||||
manager.post(urlString, parameters: nil, progress: nil, success: { (requestOperation, responseObject) in
|
||||
self.postLeaderboardAutoCourseSuccess(responseObject: responseObject, success: success, failure: failure)
|
||||
}) { (requestOperation, error) in
|
||||
self.postLeaderboardAutoCourseFailure(error: error, failure: failure)
|
||||
|
||||
+1
@@ -31,6 +31,7 @@ public enum BoatClassMasterdata {
|
||||
CANOE_TAIFUN ("Canoe Taifun", true, 5.20, 1.32, BoatHullType.MONOHULL, false, "Taifun", "Taifun Kanu", "Kanu Taifun"),
|
||||
CONTENDER ("Contender", true, 4.88, 1.42, BoatHullType.MONOHULL, false),
|
||||
CC_30 ("C&C 30", true, 9.12, 3.25, BoatHullType.MONOHULL, true),
|
||||
CLUB_SWAN_50 ("Club Swan 50", true, 16.74, 4.20, BoatHullType.MONOHULL, true, "ClubSwan50"),
|
||||
D_ONE ("D-One", true, 4.23, 2.31, BoatHullType.MONOHULL, true, "Devoti D-One", "DOne", "D_One"),
|
||||
DRAGON_INT ("Dragon Int.", true, 8.89, 1.96, BoatHullType.MONOHULL, true, "Drachen", "Dragon"),
|
||||
DELPHIA_24 ("Delphia 24", true, 7.70, 2.50, BoatHullType.MONOHULL, true, "Delphia 24 One Design", "Delphia 24 OD"),
|
||||
|
||||
+145
-79
@@ -5,10 +5,9 @@ import static com.sap.sailing.domain.common.SortingOrder.DESCENDING;
|
||||
import static com.sap.sailing.domain.common.SortingOrder.NONE;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
/**
|
||||
* Identifies details that can be requested from the racing service. Optionally, the details can specify a precision as
|
||||
@@ -244,11 +243,11 @@ public enum DetailType implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Special List of DetailTypes, that allows operators to select for example the RideHeight, that is usually only
|
||||
* selectable, if it already has data.
|
||||
* Special collection of {@link DetailType}s, that allows operators to select for example the RideHeight, that is
|
||||
* usually only selectable, if it already has data.
|
||||
*/
|
||||
public static List<DetailType> getAutoplayDetailTypesForChart() {
|
||||
List<DetailType> availableDetailsTypes = new ArrayList<>();
|
||||
public static Collection<DetailType> getAutoplayDetailTypesForChart() {
|
||||
final Collection<DetailType> availableDetailsTypes = new LinkedHashSet<>();
|
||||
availableDetailsTypes.add(DetailType.CHART_WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD);
|
||||
availableDetailsTypes.add(DetailType.LEG_CURRENT_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
availableDetailsTypes.add(DetailType.LEG_DISTANCE_TRAVELED);
|
||||
@@ -266,8 +265,8 @@ public enum DetailType implements Serializable {
|
||||
return availableDetailsTypes;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceExpeditionDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getRaceExpeditionDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(EXPEDITION_RACE_AWA);
|
||||
allowed.add(EXPEDITION_RACE_AWS);
|
||||
allowed.add(EXPEDITION_RACE_TWA);
|
||||
@@ -310,15 +309,15 @@ public enum DetailType implements Serializable {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegExtendedBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getLegExtendedBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(DetailType.BRAVOEXTENDED_LEG_CURRENT_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_LEG_CURRENT_DURATION_FOILED_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceExtendedBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getRaceExtendedBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(DetailType.BRAVOEXTENDED_RACE_CURRENT_PORT_DAGGERBOARD_RAKE);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_RACE_CURRENT_STBD_DAGGERBOARD_RAKE);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_RACE_CURRENT_PORT_RUDDER_RAKE);
|
||||
@@ -340,24 +339,24 @@ public enum DetailType implements Serializable {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getRaceBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(DetailType.BRAVO_RACE_HEEL_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_RACE_PITCH_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_RACE_CURRENT_RIDE_HEIGHT_IN_METERS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getLegBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(DetailType.BRAVO_LEG_CURRENT_HEEL_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_LEG_CURRENT_PITCH_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_LEG_CURRENT_RIDE_HEIGHT_IN_METERS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getAllRaceDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getAllRaceDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(RACE_GAP_TO_LEADER_IN_SECONDS);
|
||||
allowed.add(RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(RACE_DISTANCE_TRAVELED);
|
||||
@@ -366,7 +365,6 @@ public enum DetailType implements Serializable {
|
||||
allowed.add(RACE_CALCULATED_TIME_TRAVELED);
|
||||
allowed.add(RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD);
|
||||
allowed.add(RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(BRAVO_RACE_CURRENT_RIDE_HEIGHT_IN_METERS);
|
||||
allowed.add(RACE_CURRENT_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(RACE_CURRENT_DURATION_FOILED_IN_SECONDS);
|
||||
allowed.add(RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS);
|
||||
@@ -388,7 +386,7 @@ public enum DetailType implements Serializable {
|
||||
* @return
|
||||
*/
|
||||
public static Collection<DetailType> getAllNonRestrictedDetailTypes() {
|
||||
List<DetailType> all = new ArrayList<>(Arrays.asList(values()));
|
||||
final Collection<DetailType> all = new LinkedHashSet<>(Arrays.asList(values()));
|
||||
all.removeAll(getRaceBravoDetailTypes());
|
||||
all.removeAll(getLegBravoDetailTypes());
|
||||
all.removeAll(getRaceExtendedBravoDetailTypes());
|
||||
@@ -398,80 +396,148 @@ public enum DetailType implements Serializable {
|
||||
return all;
|
||||
}
|
||||
|
||||
public static List<DetailType> getAvailableOverallDetailColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.REGATTA_RANK, DetailType.OVERALL_TOTAL_DISTANCE_TRAVELED,
|
||||
DetailType.OVERALL_TOTAL_AVERAGE_SPEED_OVER_GROUND, DetailType.OVERALL_TOTAL_TIME_SAILED_IN_SECONDS,
|
||||
DetailType.OVERALL_MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS, DetailType.OVERALL_TIME_ON_TIME_FACTOR,
|
||||
DetailType.OVERALL_TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE,
|
||||
DetailType.OVERALL_TOTAL_SCORED_RACE_COUNT, TOTAL_TIME_SAILED_UPWIND_IN_SECONDS,
|
||||
TOTAL_TIME_SAILED_REACHING_IN_SECONDS, TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS });
|
||||
public static Collection<DetailType> getAvailableOverallDetailColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(REGATTA_RANK);
|
||||
allowed.add(OVERALL_TOTAL_DISTANCE_TRAVELED);
|
||||
allowed.add(OVERALL_TOTAL_AVERAGE_SPEED_OVER_GROUND);
|
||||
allowed.add(OVERALL_TOTAL_TIME_SAILED_IN_SECONDS);
|
||||
allowed.add(OVERALL_MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(OVERALL_TIME_ON_TIME_FACTOR);
|
||||
allowed.add(OVERALL_TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE);
|
||||
allowed.add(OVERALL_TOTAL_SCORED_RACE_COUNT);
|
||||
allowed.add(TOTAL_TIME_SAILED_UPWIND_IN_SECONDS);
|
||||
allowed.add(TOTAL_TIME_SAILED_REACHING_IN_SECONDS);
|
||||
allowed.add(TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getOverallBravoDetailTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.OVERALL_TOTAL_DISTANCE_FOILED_IN_METERS,
|
||||
OVERALL_TOTAL_DURATION_FOILED_IN_SECONDS });
|
||||
public static Collection<DetailType> getOverallBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(OVERALL_TOTAL_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(OVERALL_TOTAL_DURATION_FOILED_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegDetailColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS,
|
||||
DetailType.LEG_DISTANCE_TRAVELED, DetailType.LEG_DISTANCE_TRAVELED_INCLUDING_GATE_START,
|
||||
DetailType.LEG_GAP_TO_LEADER_IN_SECONDS, DetailType.LEG_GAP_CHANGE_SINCE_LEG_START_IN_SECONDS,
|
||||
DetailType.LEG_SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED,
|
||||
DetailType.LEG_CURRENT_SPEED_OVER_GROUND_IN_KNOTS, DetailType.LEG_WINDWARD_DISTANCE_TO_GO_IN_METERS,
|
||||
DetailType.NUMBER_OF_MANEUVERS, DetailType.LEG_ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS,
|
||||
DetailType.LEG_VELOCITY_MADE_GOOD_IN_KNOTS, DetailType.LEG_TIME_TRAVELED,
|
||||
DetailType.LEG_CORRECTED_TIME_TRAVELED, DetailType.LEG_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS,
|
||||
DetailType.LEG_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS, DetailType.LEG_RANK_GAIN });
|
||||
public static Collection<DetailType> getLegDetailColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(LEG_DISTANCE_TRAVELED);
|
||||
allowed.add(LEG_DISTANCE_TRAVELED_INCLUDING_GATE_START);
|
||||
allowed.add(LEG_GAP_TO_LEADER_IN_SECONDS);
|
||||
allowed.add(LEG_GAP_CHANGE_SINCE_LEG_START_IN_SECONDS);
|
||||
allowed.add(LEG_SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED);
|
||||
allowed.add(LEG_CURRENT_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(LEG_WINDWARD_DISTANCE_TO_GO_IN_METERS);
|
||||
allowed.add(NUMBER_OF_MANEUVERS);
|
||||
allowed.add(LEG_ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS);
|
||||
allowed.add(LEG_VELOCITY_MADE_GOOD_IN_KNOTS);
|
||||
allowed.add(LEG_TIME_TRAVELED);
|
||||
allowed.add(LEG_CORRECTED_TIME_TRAVELED);
|
||||
allowed.add(LEG_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS);
|
||||
allowed.add(LEG_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS);
|
||||
allowed.add(LEG_RANK_GAIN);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceStartAnalysisColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START,
|
||||
DetailType.RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START, DetailType.DISTANCE_TO_START_AT_RACE_START,
|
||||
DetailType.TIME_BETWEEN_RACE_START_AND_COMPETITOR_START, DetailType.SPEED_OVER_GROUND_AT_RACE_START,
|
||||
DetailType.SPEED_OVER_GROUND_WHEN_PASSING_START,
|
||||
DetailType.DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS,
|
||||
DetailType.START_TACK });
|
||||
public static Collection<DetailType> getRaceStartAnalysisColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START);
|
||||
allowed.add(RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START);
|
||||
allowed.add(DISTANCE_TO_START_AT_RACE_START);
|
||||
allowed.add(TIME_BETWEEN_RACE_START_AND_COMPETITOR_START);
|
||||
allowed.add(SPEED_OVER_GROUND_AT_RACE_START);
|
||||
allowed.add(SPEED_OVER_GROUND_WHEN_PASSING_START);
|
||||
allowed.add(DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS);
|
||||
allowed.add(START_TACK);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegExpeditionDetailColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { EXPEDITION_LEG_AWA, EXPEDITION_LEG_AWS, EXPEDITION_LEG_TWA,
|
||||
EXPEDITION_LEG_TWS, EXPEDITION_LEG_TWD, EXPEDITION_LEG_TARG_TWA, EXPEDITION_LEG_BOAT_SPEED,
|
||||
EXPEDITION_LEG_TARG_BOAT_SPEED, EXPEDITION_LEG_SOG, EXPEDITION_LEG_COG, EXPEDITION_LEG_FORESTAY_LOAD,
|
||||
EXPEDITION_LEG_RAKE, EXPEDITION_LEG_COURSE, EXPEDITION_LEG_HEADING, EXPEDITION_LEG_VMG,
|
||||
EXPEDITION_LEG_VMG_TARG_VMG_DELTA, EXPEDITION_LEG_RATE_OF_TURN, EXPEDITION_LEG_RUDDER_ANGLE,
|
||||
EXPEDITION_LEG_TARGET_HEEL, EXPEDITION_LEG_TIME_TO_PORT_LAYLINE,
|
||||
EXPEDITION_LEG_TIME_TO_STB_LAYLINE, EXPEDITION_LEG_DIST_TO_PORT_LAYLINE,
|
||||
EXPEDITION_LEG_DIST_TO_STB_LAYLINE, EXPEDITION_LEG_TIME_TO_GUN, EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_LEG_TIME_TO_PIN, EXPEDITION_LEG_TIME_TO_BURN_TO_LINE,
|
||||
EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT, EXPEDITION_LEG_TIME_TO_BURN_TO_PIN,
|
||||
EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT, EXPEDITION_LEG_DISTANCE_TO_PIN,
|
||||
EXPEDITION_LEG_DISTANCE_BELOW_LINE, EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION, EXPEDITION_LEG_BARO,
|
||||
EXPEDITION_LEG_LOAD_S, EXPEDITION_LEG_LOAD_P, EXPEDITION_LEG_JIB_CAR_PORT, EXPEDITION_LEG_JIB_CAR_STBD,
|
||||
EXPEDITION_LEG_MAST_BUTT });
|
||||
public static Collection<DetailType> getLegExpeditionDetailColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(EXPEDITION_LEG_AWA);
|
||||
allowed.add(EXPEDITION_LEG_AWS);
|
||||
allowed.add(EXPEDITION_LEG_TWA);
|
||||
allowed.add(EXPEDITION_LEG_TWS);
|
||||
allowed.add(EXPEDITION_LEG_TWD);
|
||||
allowed.add(EXPEDITION_LEG_TARG_TWA);
|
||||
allowed.add(EXPEDITION_LEG_BOAT_SPEED);
|
||||
allowed.add(EXPEDITION_LEG_TARG_BOAT_SPEED);
|
||||
allowed.add(EXPEDITION_LEG_SOG);
|
||||
allowed.add(EXPEDITION_LEG_COG);
|
||||
allowed.add(EXPEDITION_LEG_FORESTAY_LOAD);
|
||||
allowed.add(EXPEDITION_LEG_RAKE);
|
||||
allowed.add(EXPEDITION_LEG_COURSE);
|
||||
allowed.add(EXPEDITION_LEG_HEADING);
|
||||
allowed.add(EXPEDITION_LEG_VMG);
|
||||
allowed.add(EXPEDITION_LEG_VMG_TARG_VMG_DELTA);
|
||||
allowed.add(EXPEDITION_LEG_RATE_OF_TURN);
|
||||
allowed.add(EXPEDITION_LEG_RUDDER_ANGLE);
|
||||
allowed.add(EXPEDITION_LEG_TARGET_HEEL);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_PORT_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_STB_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_DIST_TO_PORT_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_DIST_TO_STB_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_GUN);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_PIN);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_BURN_TO_LINE);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_BURN_TO_PIN);
|
||||
allowed.add(EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT);
|
||||
allowed.add(EXPEDITION_LEG_DISTANCE_TO_PIN);
|
||||
allowed.add(EXPEDITION_LEG_DISTANCE_BELOW_LINE);
|
||||
allowed.add(EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION);
|
||||
allowed.add(EXPEDITION_LEG_BARO);
|
||||
allowed.add(EXPEDITION_LEG_LOAD_S);
|
||||
allowed.add(EXPEDITION_LEG_LOAD_P);
|
||||
allowed.add(EXPEDITION_LEG_JIB_CAR_PORT);
|
||||
allowed.add(EXPEDITION_LEG_JIB_CAR_STBD);
|
||||
allowed.add(EXPEDITION_LEG_MAST_BUTT);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not yet implemented types can be added here, they will be hidden from any user under all circumstances
|
||||
*/
|
||||
public static List<DetailType> getDisabledDetailColumTypes() {
|
||||
return Arrays.asList(new DetailType[] { EXPEDITION_LEG_TARG_TWA, EXPEDITION_LEG_VMG,
|
||||
EXPEDITION_LEG_VMG_TARG_VMG_DELTA, EXPEDITION_LEG_RATE_OF_TURN, EXPEDITION_LEG_RUDDER_ANGLE,
|
||||
EXPEDITION_LEG_TIME_TO_PORT_LAYLINE, EXPEDITION_LEG_TIME_TO_STB_LAYLINE,
|
||||
EXPEDITION_LEG_DIST_TO_PORT_LAYLINE, EXPEDITION_LEG_DIST_TO_STB_LAYLINE,
|
||||
EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT, EXPEDITION_LEG_TIME_TO_PIN, EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_LEG_TIME_TO_BURN_TO_PIN, EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_LEG_DISTANCE_TO_PIN, EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION, EXPEDITION_RACE_TARG_TWA,
|
||||
EXPEDITION_RACE_VMG, EXPEDITION_RACE_VMG_TARG_VMG_DELTA,
|
||||
EXPEDITION_RACE_RUDDER_ANGLE, EXPEDITION_RACE_TIME_TO_PORT_LAYLINE, EXPEDITION_RACE_TIME_TO_STB_LAYLINE,
|
||||
EXPEDITION_RACE_DIST_TO_PORT_LAYLINE, EXPEDITION_RACE_DIST_TO_STB_LAYLINE,
|
||||
EXPEDITION_RACE_TIME_TO_COMMITTEE_BOAT, EXPEDITION_RACE_TIME_TO_PIN,
|
||||
EXPEDITION_RACE_TIME_TO_BURN_TO_PIN, EXPEDITION_RACE_TIME_TO_BURN_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_RACE_DISTANCE_TO_COMMITTEE_BOAT, EXPEDITION_RACE_DISTANCE_TO_PIN,
|
||||
EXPEDITION_RACE_LINE_SQUARE_FOR_WIND_DIRECTION });
|
||||
public static Collection<DetailType> getDisabledDetailColumTypes() {
|
||||
final Collection<DetailType> disabled = new LinkedHashSet<>();
|
||||
disabled.add(EXPEDITION_LEG_TARG_TWA);
|
||||
disabled.add(EXPEDITION_LEG_VMG);
|
||||
disabled.add(EXPEDITION_LEG_VMG_TARG_VMG_DELTA);
|
||||
disabled.add(EXPEDITION_LEG_RATE_OF_TURN);
|
||||
disabled.add(EXPEDITION_LEG_RUDDER_ANGLE);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_DIST_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_DIST_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_PIN);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_BURN_TO_PIN);
|
||||
disabled.add(EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_LEG_DISTANCE_TO_PIN);
|
||||
disabled.add(EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION);
|
||||
disabled.add(EXPEDITION_RACE_TARG_TWA);
|
||||
disabled.add(EXPEDITION_RACE_VMG);
|
||||
disabled.add(EXPEDITION_RACE_VMG_TARG_VMG_DELTA);
|
||||
disabled.add(EXPEDITION_RACE_RUDDER_ANGLE);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_DIST_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_DIST_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_PIN);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_BURN_TO_PIN);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_BURN_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_RACE_DISTANCE_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_RACE_DISTANCE_TO_PIN);
|
||||
disabled.add(EXPEDITION_RACE_LINE_SQUARE_FOR_WIND_DIRECTION);
|
||||
return disabled;
|
||||
}
|
||||
|
||||
public static List<DetailType> getAllLegDetailColumnTypes() {
|
||||
ArrayList<DetailType> all = new ArrayList<>();
|
||||
public static Collection<DetailType> getAllLegDetailColumnTypes() {
|
||||
final Collection<DetailType> all = new LinkedHashSet<>();
|
||||
all.addAll(getLegDetailColumnTypes());
|
||||
all.addAll(getLegBravoDetailTypes());
|
||||
all.addAll(getLegExtendedBravoDetailTypes());
|
||||
|
||||
+15
-8
@@ -5,6 +5,7 @@ import java.io.ObjectInputStream;
|
||||
import java.net.URI;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Nationality;
|
||||
import com.sap.sailing.domain.base.NationalityChangeListener;
|
||||
@@ -15,6 +16,7 @@ import com.sap.sse.common.impl.NamedImpl;
|
||||
|
||||
public class TeamImpl extends NamedImpl implements DynamicTeam {
|
||||
private static final long serialVersionUID = 4646922280429210183L;
|
||||
private static final Logger logger = Logger.getLogger(TeamImpl.class.getName());
|
||||
private final Iterable<? extends DynamicPerson> sailors;
|
||||
private final DynamicPerson coach;
|
||||
private final NationalityChangeListener personNationalityChangeForwarder;
|
||||
@@ -116,14 +118,19 @@ public class TeamImpl extends NamedImpl implements DynamicTeam {
|
||||
public void setNationality(Nationality newNationality) {
|
||||
Nationality oldNationality = getNationality();
|
||||
if (!Util.equalsWithNull(oldNationality, newNationality)) {
|
||||
for (Person sailor : getSailors()) {
|
||||
((DynamicPerson) sailor).setNationality(newNationality);
|
||||
}
|
||||
if (getCoach() != null) {
|
||||
getCoach().setNationality(newNationality);
|
||||
}
|
||||
for (NationalityChangeListener listener : getNationalityChangeListeners()) {
|
||||
listener.nationalityChanged(this, oldNationality, newNationality);
|
||||
if (Util.isEmpty(getSailors()) && getCoach() == null) {
|
||||
logger.warning("Would like to update nationality of team "+this+
|
||||
" to "+newNationality+" but cannot because neither sailors nor coach are set");
|
||||
} else {
|
||||
for (Person sailor : getSailors()) {
|
||||
((DynamicPerson) sailor).setNationality(newNationality);
|
||||
}
|
||||
if (getCoach() != null) {
|
||||
getCoach().setNationality(newNationality);
|
||||
}
|
||||
for (NationalityChangeListener listener : getNationalityChangeListeners()) {
|
||||
listener.nationalityChanged(this, oldNationality, newNationality);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-4
@@ -127,10 +127,16 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
CompetitorWithBoat domainCompetitor = competitorAndBoatStore.getExistingCompetitorWithBoatById(competitorId);
|
||||
if (domainCompetitor == null || competitorAndBoatStore.isCompetitorToUpdateDuringGetOrCreate(domainCompetitor)) {
|
||||
List<DynamicPerson> teamMembers = new ArrayList<DynamicPerson>();
|
||||
for (CrewMember crewMember: competitor.getCrew()) {
|
||||
DynamicPerson person = new PersonImpl(crewMember.getName().trim(), getOrCreateNationality(crewMember.getNationality()),
|
||||
/* dateOfBirth */ null, crewMember.getPosition());
|
||||
teamMembers.add(person);
|
||||
if (competitor.getCrew().isEmpty()) {
|
||||
DynamicPerson dummyPerson = new PersonImpl(competitor.getName().trim(), getOrCreateNationality(competitor.getThreeLetterIOCCode()),
|
||||
/* dateOfBirth */ null, /* description */ "Team");
|
||||
teamMembers.add(dummyPerson);
|
||||
} else {
|
||||
for (CrewMember crewMember: competitor.getCrew()) {
|
||||
DynamicPerson person = new PersonImpl(crewMember.getName().trim(), getOrCreateNationality(crewMember.getNationality()),
|
||||
/* dateOfBirth */ null, crewMember.getPosition());
|
||||
teamMembers.add(person);
|
||||
}
|
||||
}
|
||||
DynamicTeam team = new TeamImpl(competitor.getName(), teamMembers, /* coach */ null);
|
||||
final DynamicBoat domainBoat = competitorAndBoatStore.getOrCreateBoat(competitorId, /* name */ null, boatClass, competitor.getBoatID(), /* color */ null);
|
||||
|
||||
+1
-3
@@ -120,9 +120,7 @@ public class SwissTimingAdapterImpl implements SwissTimingAdapter {
|
||||
person.getGivenName() + " " + person.getFamilyName(),
|
||||
person.getNOC().name(), crewMember.getPosition().name()));
|
||||
}
|
||||
Crew firstCrewMember = team.getCrew().get(0);
|
||||
Person person = persons.get(firstCrewMember.getPersonID());
|
||||
String nationality = person.getNOC().name();
|
||||
String nationality = team.getNOC().name();
|
||||
CompetitorWithID competitor = new CompetitorWithID(team.getTeamID(),
|
||||
boat.getSailNumber(), nationality, team.getTeamName(), crew);
|
||||
competitors.add(competitor);
|
||||
|
||||
@@ -29,7 +29,7 @@ html {
|
||||
|
||||
|
||||
body {
|
||||
background: url(images/spectatorview-bg.png) no-repeat left top #ebebeb;
|
||||
background: #eee;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
@@ -150,11 +150,6 @@ input.magnifier {
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.mainPanel {
|
||||
width: 100%;
|
||||
margin-left: 13px;
|
||||
}
|
||||
|
||||
.errorLabel {
|
||||
color: #FF0000;
|
||||
}
|
||||
@@ -221,15 +216,32 @@ input.magnifier {
|
||||
top: 9px;
|
||||
}
|
||||
|
||||
.groupingProvider {
|
||||
padding: 3px 0px;
|
||||
}
|
||||
|
||||
.groupingProviderElement {
|
||||
margin: 2px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.statisticProvider {
|
||||
padding: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.statisticProviderElement {
|
||||
margin: 10px 2px 2px 2px;
|
||||
margin: 2px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.statisticSuggestBoxPopup {
|
||||
z-index: 2;
|
||||
}
|
||||
.statisticSuggestBoxPopup .suggestPopupContent {
|
||||
max-height: 700px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.definitionProviderControls {
|
||||
margin: 2px;
|
||||
}
|
||||
@@ -238,14 +250,17 @@ input.magnifier {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.queryProviderElementLabel {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.queryDefinitionViewerContent {
|
||||
background-color: white;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.statisticSuggestBoxPopup .suggestPopupContent {
|
||||
max-height: 700px;
|
||||
overflow-y: scroll;
|
||||
.filterDimensionsTitleLabel {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.filterFilterDimensionsPanel {
|
||||
@@ -254,7 +269,6 @@ input.magnifier {
|
||||
|
||||
.dimensionFilterSelectionTablesContainer {
|
||||
overflow-x: auto;
|
||||
border-left: 2px solid #6f7277;
|
||||
}
|
||||
|
||||
.dimensionFilterSelectionHeader {
|
||||
@@ -267,6 +281,58 @@ input.magnifier {
|
||||
text-shadow: #ddf 1px 1px 0;
|
||||
}
|
||||
|
||||
.dimensionFilterSelectionTable {
|
||||
border-top: 2px solid #6f7277;
|
||||
.dataMiningBorderTop {
|
||||
border-top: 2px solid #6f7277;
|
||||
}
|
||||
.dataMiningBorderLeft {
|
||||
border-left: 2px solid #6f7277;
|
||||
}
|
||||
.dataMiningBorderBottom {
|
||||
border-border: 2px solid #6f7277;
|
||||
}
|
||||
.dataMiningBorderRight {
|
||||
border-right: 2px solid #6f7277;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-VDragger {
|
||||
background: #fff url(images/thumb_horz.png) center center no-repeat;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
left: 0 !important;
|
||||
top: 0 !important;
|
||||
border: none;
|
||||
border-radius: 0px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-HDragger {
|
||||
background: #fff url(images/thumb_vertical.png) center center no-repeat;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
left: 0 !important;
|
||||
top: 0 !important;
|
||||
border: none;
|
||||
border-radius: 0px;
|
||||
margin: 0px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dataMiningMarginBase {
|
||||
margin: 0px 5px;
|
||||
}
|
||||
.dataMiningMarginLeft {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.dataMiningMarginRight {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.resultsPresenterTabHeader * {
|
||||
display: inline-block;
|
||||
margin: 0px 3px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.emphasizedLabel {
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.github.sdbg.debug.core.chromeLaunchConfig">
|
||||
<stringAttribute key="applicationArguments" value=""/>
|
||||
<stringAttribute key="applicationName" value=""/>
|
||||
<booleanAttribute key="launchFile" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="projectName" value="com.sap.sailing.gwt.ui"/>
|
||||
<booleanAttribute key="showLaunchOutput" value="false"/>
|
||||
<stringAttribute key="url" value="http://127.0.0.1:8888/gwt/DataMining.html"/>
|
||||
<stringAttribute key="urlQueryParams" value=""/>
|
||||
</launchConfiguration>
|
||||
+17
-6
@@ -1,10 +1,13 @@
|
||||
package com.sap.sailing.gwt.autoplay.client.configs;
|
||||
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sailing.gwt.autoplay.client.app.AutoPlayClientFactory;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.gwt.settings.UrlBuilderUtil;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
public abstract class AutoPlayConfiguration {
|
||||
@@ -19,20 +22,28 @@ public abstract class AutoPlayConfiguration {
|
||||
OnSettingsCallback holder, PerspectiveCompositeSettings<?> settings, AutoPlayContextDefinition apcd,
|
||||
UserService userService) {
|
||||
Window.alert("This configuration does not have settings");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be pure/standalone, it is not allowed to make any guesses on fields written by startRootNode,
|
||||
* as it can be called before that
|
||||
*/
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, StrippedLeaderboardDTO leaderboard, UserService userService,
|
||||
OnSettingsCallback holder) {
|
||||
holder.newSettings(null);
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, AutoPlayContextDefinition apcd,
|
||||
StrippedLeaderboardDTO leaderboard, UserService userService, OnSettingsCallback holder) {
|
||||
holder.newSettings(null, getUrlWithSettings(apcd, null));
|
||||
}
|
||||
|
||||
private String getUrlWithSettings(AutoPlayContextDefinition apcd, PerspectiveCompositeSettings<?> settings) {
|
||||
UrlBuilder urlBuilder = UrlBuilderUtil.createUrlBuilderFromCurrentLocationWithCleanParameters();
|
||||
SettingsToUrlSerializer urlSerializer = new SettingsToUrlSerializer();
|
||||
if (settings != null) {
|
||||
urlSerializer.serializeSettingsMapToUrlBuilder(settings, urlBuilder);
|
||||
}
|
||||
urlSerializer.serializeToUrlBuilder(apcd, urlBuilder);
|
||||
return urlBuilder.buildString();
|
||||
}
|
||||
|
||||
public interface OnSettingsCallback {
|
||||
void newSettings(PerspectiveCompositeSettings<?> newSettings);
|
||||
void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+55
-32
@@ -26,58 +26,81 @@ import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
public class AutoPlayClassicConfiguration extends AutoPlayConfiguration {
|
||||
private static final Logger logger = Logger.getLogger(AutoPlayClassicConfiguration.class.getName());
|
||||
|
||||
|
||||
@Override
|
||||
public void startRootNode(AutoPlayClientFactory cf, AutoPlayContextDefinition context,
|
||||
PerspectiveCompositeSettings<?> settings, EventDTO initialEventData) {
|
||||
cf.getSailingService().getAvailableDetailTypesForLeaderboard(context.getLeaderboardName(), new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
logger.log(Level.WARNING, "Could not load detailtypes for leaderboard", caught);
|
||||
}
|
||||
cf.getSailingService().getAvailableDetailTypesForLeaderboard(context.getLeaderboardName(),
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
logger.log(Level.WARNING, "Could not load detailtypes for leaderboard", caught);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
StrippedLeaderboardDTO leaderBoardDTO = AutoplayHelper.getSelectedLeaderboard(initialEventData,
|
||||
context.getLeaderboardName());
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderBoardDTO, cf.getUserService(), result);
|
||||
cf.setAutoPlayContext(new AutoPlayContextImpl(autoplayLifecycle,
|
||||
(PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>) settings,
|
||||
AutoPlayClassicConfiguration.this, context, initialEventData));
|
||||
// start sixty inch slide loop nodes...
|
||||
RootNodeClassic root = new RootNodeClassic(cf);
|
||||
root.start(cf.getEventBus());
|
||||
}
|
||||
});
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
StrippedLeaderboardDTO leaderBoardDTO = AutoplayHelper.getSelectedLeaderboard(initialEventData,
|
||||
context.getLeaderboardName());
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(
|
||||
leaderBoardDTO, cf.getUserService(), result);
|
||||
cf.setAutoPlayContext(new AutoPlayContextImpl(autoplayLifecycle,
|
||||
(PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>) settings,
|
||||
AutoPlayClassicConfiguration.this, context, initialEventData));
|
||||
// start sixty inch slide loop nodes...
|
||||
RootNodeClassic root = new RootNodeClassic(cf);
|
||||
root.start(cf.getEventBus());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openSettingsDialog(EventDTO selectedEvent, StrippedLeaderboardDTO leaderboard,
|
||||
OnSettingsCallback settingsCallback, PerspectiveCompositeSettings<?> settings, AutoPlayContextDefinition apcd, UserService userService) {
|
||||
OnSettingsCallback settingsCallback, PerspectiveCompositeSettings<?> settings,
|
||||
AutoPlayContextDefinition apcd, UserService userService) {
|
||||
DialogCallback<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> callback = new DialogCallback<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>>() {
|
||||
@Override
|
||||
public void ok(PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> editedObject) {
|
||||
settingsCallback.newSettings(editedObject);
|
||||
settingsCallback.newSettings(editedObject,
|
||||
getUrlWithSettings(apcd, editedObject, leaderboard, userService));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
};
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService, Arrays.asList(DetailType.values()));
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> autoplayPerspectiveSettings = autoplayLifecycle
|
||||
.createDefaultSettings();
|
||||
LinkWithSettingsGenerator<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> settingsGenerator = new LinkWithSettingsGenerator<>(Window.Location.getPath(), autoplayLifecycle::createDefaultSettings, apcd);
|
||||
new SettingsDialogForLinkSharing<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>>(settingsGenerator,
|
||||
autoplayLifecycle, autoplayPerspectiveSettings, StringMessages.INSTANCE, true, callback).show();
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService,
|
||||
Arrays.asList(DetailType.values()));
|
||||
@SuppressWarnings("unchecked")
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> autoplayPerspectiveSettings = settings != null
|
||||
? (PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>) settings
|
||||
: autoplayLifecycle.createDefaultSettings();
|
||||
LinkWithSettingsGenerator<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> settingsGenerator = new LinkWithSettingsGenerator<>(
|
||||
Window.Location.getPath(), autoplayLifecycle::createDefaultSettings, apcd);
|
||||
new SettingsDialogForLinkSharing<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>>(
|
||||
settingsGenerator, autoplayLifecycle, autoplayPerspectiveSettings, StringMessages.INSTANCE, true,
|
||||
callback).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, StrippedLeaderboardDTO leaderboard,
|
||||
UserService userService, OnSettingsCallback settingsCallback) {
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService, Arrays.asList(DetailType.values()));
|
||||
settingsCallback.newSettings(autoplayLifecycle.createDefaultSettings());
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, AutoPlayContextDefinition apcd,
|
||||
StrippedLeaderboardDTO leaderboard, UserService userService, OnSettingsCallback settingsCallback) {
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService,
|
||||
Arrays.asList(DetailType.values()));
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> defaultSettings = autoplayLifecycle
|
||||
.createDefaultSettings();
|
||||
settingsCallback.newSettings(defaultSettings,
|
||||
getUrlWithSettings(apcd, defaultSettings, leaderboard, userService));
|
||||
}
|
||||
|
||||
private String getUrlWithSettings(AutoPlayContextDefinition apcd,
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> settings, StrippedLeaderboardDTO leaderboard,
|
||||
UserService userService) {
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService,
|
||||
Arrays.asList(DetailType.values()));
|
||||
LinkWithSettingsGenerator<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> settingsGenerator = new LinkWithSettingsGenerator<>(
|
||||
Window.Location.getPath(), autoplayLifecycle::createDefaultSettings, apcd);
|
||||
|
||||
return settingsGenerator.createUrl(settings);
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -17,6 +17,7 @@ import com.sap.sailing.gwt.autoplay.client.utils.AutoplayHelper;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
@@ -35,6 +36,7 @@ public class IdleRaceLeaderboard extends FiresPlaceNode {
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
leaderboardTimer.setTime(MillisecondsTimePoint.now().asMillis());
|
||||
leaderboardTimer.play();
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> settings = cf.getAutoPlayCtxSignalError()
|
||||
.getAutoplaySettings();
|
||||
|
||||
+3
@@ -24,6 +24,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.raceboard.RaceBoardPanel;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceboardDataDTO;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
@@ -54,6 +55,8 @@ public class LiveRaceBoardNode extends FiresPlaceNode implements RaceTimesInfoPr
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
raceboardTimer.setTime(MillisecondsTimePoint.now().asMillis());
|
||||
raceboardTimer.play();
|
||||
raceTimesInfoProvider.addRaceIdentifier(cf.getAutoPlayCtxSignalError().getLifeOrPreLiveRace(), true);
|
||||
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> settings = cf.getAutoPlayCtxSignalError().getAutoplaySettings();
|
||||
|
||||
+2
-2
@@ -55,10 +55,10 @@ public class AutoPlayStartPresenterImpl extends AbstractActivity implements Auto
|
||||
StrippedLeaderboardDTO leaderBoard = AutoplayHelper.getSelectedLeaderboard(event,
|
||||
apcd.getLeaderboardName());
|
||||
|
||||
apcd.getType().getConfig().loadSettingsDefault(event, leaderBoard, clientFactory.getUserService(), new OnSettingsCallback() {
|
||||
apcd.getType().getConfig().loadSettingsDefault(event, apcd, leaderBoard, clientFactory.getUserService(), new OnSettingsCallback() {
|
||||
|
||||
@Override
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings) {
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings) {
|
||||
if (newSettings != null) {
|
||||
serializer.deserializeSettingsMapFromCurrentLocation(newSettings);
|
||||
}
|
||||
|
||||
+8
-18
@@ -8,7 +8,6 @@ import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
@@ -30,8 +29,6 @@ import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.GWTLocaleUtil;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.gwt.settings.UrlBuilderUtil;
|
||||
|
||||
public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartView {
|
||||
private static StartPageViewUiBinder uiBinder = GWT.create(StartPageViewUiBinder.class);
|
||||
@@ -151,9 +148,9 @@ public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartVie
|
||||
selectedAutoPlayType.getConfig().openSettingsDialog(selectedEvent, selectedLeaderboard,
|
||||
new OnSettingsCallback() {
|
||||
@Override
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings) {
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings) {
|
||||
settings = newSettings;
|
||||
updateURL();
|
||||
updateURL(urlWithSettings);
|
||||
}
|
||||
}, settings, apcd, currentPresenter.getUserService());
|
||||
}
|
||||
@@ -197,12 +194,12 @@ public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartVie
|
||||
settingsButton.removeStyleName(SharedResources.INSTANCE.mainCss().buttoninactive());
|
||||
startAutoPlayButton.removeStyleName(SharedResources.INSTANCE.mainCss().buttoninactive());
|
||||
apcd = new AutoPlayContextDefinitionImpl(selectedAutoPlayType, selectedEvent.id, selectedLeaderboardName);
|
||||
apcd.getType().getConfig().loadSettingsDefault(selectedEvent, selectedLeaderboard, currentPresenter.getUserService(),
|
||||
apcd.getType().getConfig().loadSettingsDefault(selectedEvent, apcd, selectedLeaderboard, currentPresenter.getUserService(),
|
||||
new OnSettingsCallback() {
|
||||
@Override
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings) {
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings) {
|
||||
settings = newSettings;
|
||||
updateURL();
|
||||
updateURL(urlWithSettings);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -210,16 +207,9 @@ public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartVie
|
||||
return readyToGo;
|
||||
}
|
||||
|
||||
private void updateURL() {
|
||||
UrlBuilder urlBuilder = UrlBuilderUtil.createUrlBuilderFromCurrentLocationWithCleanParameters();
|
||||
SettingsToUrlSerializer urlSerializer = new SettingsToUrlSerializer();
|
||||
if (settings != null) {
|
||||
urlSerializer.serializeSettingsMapToUrlBuilder(settings, urlBuilder);
|
||||
}
|
||||
urlSerializer.serializeToUrlBuilder(apcd, urlBuilder);
|
||||
configuratedUrl = urlBuilder.buildString();
|
||||
configStarter.setText(configuratedUrl);
|
||||
configStarter.setHref(configuratedUrl);
|
||||
private void updateURL(String urlWithSettings) {
|
||||
configStarter.setText(urlWithSettings);
|
||||
configStarter.setHref(urlWithSettings);
|
||||
}
|
||||
|
||||
@UiHandler("localeSelectionBox")
|
||||
|
||||
+1
@@ -45,6 +45,7 @@ public class BoatClassImageResolver {
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CANOE_TAIFUN.getDisplayName(), imageResources.CanoeTaifunIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CONTENDER.getDisplayName(), imageResources.ContenderIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CC_30.getDisplayName(), imageResources.CC30Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CLUB_SWAN_50.getDisplayName(), imageResources.CLUBSWAN50Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.DELPHIA_24.getDisplayName(), imageResources.Delphia24Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.DRAGON_INT.getDisplayName(), imageResources.DragonIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.DYAS.getDisplayName(), imageResources.DyasIcon());
|
||||
|
||||
+4
@@ -396,6 +396,10 @@ public interface BoatClassImageResources extends ClientBundle {
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource CC30Icon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/CLUBSWAN50.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource CLUBSWAN50Icon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/GP_26.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource GP26Icon();
|
||||
|
||||
+1
@@ -25,6 +25,7 @@
|
||||
|
||||
.tabExtension {
|
||||
float: right;
|
||||
margin-top: .5em;
|
||||
}
|
||||
|
||||
.tabExtension > * {
|
||||
|
||||
+1
-1
@@ -20,12 +20,12 @@ public class SailorInfo extends Composite {
|
||||
FlowPanel panel = new FlowPanel();
|
||||
Style panelStyle = panel.getElement().getStyle();
|
||||
panelStyle.setDisplay(Display.INLINE_BLOCK);
|
||||
panelStyle.setVerticalAlign(VerticalAlign.BOTTOM);
|
||||
|
||||
Label sailorInfoLabel = new Label();
|
||||
sailorInfoLabel.getElement().setInnerHTML(i18n.sailorInfoLongText().replace("\n", "<br />"));
|
||||
Style labelStyle = sailorInfoLabel.getElement().getStyle();
|
||||
labelStyle.setDisplay(Display.INLINE_BLOCK);
|
||||
sailorInfoLabel.getElement().getStyle().setMarginTop(0.5, Unit.EM);
|
||||
sailorInfoLabel.getElement().getStyle().setMarginRight(0.5, Unit.EM);
|
||||
panel.add(sailorInfoLabel);
|
||||
|
||||
|
||||
+10
-8
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.home.desktop.places.event.regatta;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.dom.client.Style.TextTransform;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
@@ -65,7 +66,12 @@ public class TabletAndDesktopRegattaEventView extends Composite implements Event
|
||||
racesTabUi = new RegattaRacesTabView(flagImageResolver);
|
||||
regattaOverviewTabUi = new RegattaOverviewTabView(flagImageResolver);
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
|
||||
String sailorsInfoURL = currentPresenter.getEventDTO().getSailorsInfoWebsiteURL();
|
||||
if (sailorsInfoURL != null && !sailorsInfoURL.isEmpty()) {
|
||||
tabPanelUi.addTabExtension(new SailorInfo(sailorsInfoURL));
|
||||
}
|
||||
|
||||
if(currentPresenter.getEventDTO().getType() == EventType.SERIES) {
|
||||
final PlaceNavigation<SeriesDefaultPlace> currentEventSeriesNavigation = currentPresenter.getCurrentEventSeriesNavigation();
|
||||
Anchor seriesAnchor = new Anchor(i18n.overallLeaderboardSelection());
|
||||
@@ -82,14 +88,10 @@ public class TabletAndDesktopRegattaEventView extends Composite implements Event
|
||||
seriesAnchor.setStyleName(SharedResources.INSTANCE.mainCss().button());
|
||||
seriesAnchor.addStyleName(SharedResources.INSTANCE.mainCss().buttonprimary());
|
||||
Style style = seriesAnchor.getElement().getStyle();
|
||||
style.setFontSize(16, Unit.PX);
|
||||
style.setPadding(0.75, Unit.EM);
|
||||
style.setPaddingLeft(0.75, Unit.EM);
|
||||
style.setPaddingRight(0.75, Unit.EM);
|
||||
style.setTextTransform(TextTransform.UPPERCASE);
|
||||
tabPanelUi.addTabExtension(seriesAnchor);
|
||||
} else {
|
||||
String sailorsInfoURL = currentPresenter.getEventDTO().getSailorsInfoWebsiteURL();
|
||||
if(sailorsInfoURL != null && ! sailorsInfoURL.isEmpty()) {
|
||||
tabPanelUi.addTabExtension(new SailorInfo(sailorsInfoURL));
|
||||
}
|
||||
}
|
||||
|
||||
final Iterable<SpotDTO> spots = currentPresenter.getEventDTO().getAllWindFinderSpotIdsUsedByEvent();
|
||||
|
||||
+2
-4
@@ -9,6 +9,7 @@
|
||||
<li>In <tt>RaceBoard.html</tt> the availability of media is now visualized under the time slider via a bar overlay. When hovering the bar, the title of the video is shown.</li>
|
||||
<li>In <tt>RaceBoard.html</tt> video players are now ensured to be on top of all video players when clicking/touching them.
|
||||
This means you can bring a specific video window in the foreground in case there are multiple ones that overlap each other.</li>
|
||||
<li>In <tt>RaceBoard.html</tt> the various areas (e.g. leaderboard and charts) now keep their size on expansion/collapsion.</li>
|
||||
<li>The filter selection in <tt>DataMining.html</tt> has been overhauled.
|
||||
<ul class="bulletList">
|
||||
<li>All available filter dimensions are now listed where the different data retriever levels have been listed previously.
|
||||
@@ -18,13 +19,10 @@
|
||||
<li>Selecting a filter dimension adds a table containing the available values of the selected dimension. The order of
|
||||
the value tables is equal to the order of the dimensions list.
|
||||
</li>
|
||||
<li>Note that the selection of the filter dimensions follows the <q>table with checkbox column</q> pattern. So simply clicking on a
|
||||
dimension will result in deselecting all previously selected dimensions, removing possible filter values. Clicking on the
|
||||
checkbox column or using <q>ctrl+click</q> is advised.
|
||||
</li>
|
||||
<li>Each filter value table now has its own scroll-bar.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The grouping dimensions are now ordered alphabetically.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2018</h5>
|
||||
|
||||
+9
-5
@@ -6,6 +6,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
@@ -39,9 +40,11 @@ public abstract class AbstractEventView<P extends EventViewBase.Presenter> exten
|
||||
static class AbstractEventViewLayout {
|
||||
@UiField(provided = true) EventHeader eventHeaderUi;
|
||||
@UiField Quickfinder quickFinderUi;
|
||||
@UiField SimpleInfoBlock simpleInfoUi;
|
||||
@UiField SimpleInfoBlock sailorInfoUi;
|
||||
@UiField SimpleInfoBlock seriesNavigationoUi;
|
||||
@UiField DivElement windfinderWrapperUi;
|
||||
@UiField(provided = true) WindfinderControl windfinderUi;
|
||||
@UiField SimplePanel viewContentUi;;
|
||||
@UiField SimplePanel viewContentUi;
|
||||
|
||||
private AbstractEventViewLayout(EventViewDTO event, String regattaName, PlaceNavigation<?> logoNavigation) {
|
||||
this.eventHeaderUi = new EventHeader(event, regattaName, logoNavigation);
|
||||
@@ -125,18 +128,19 @@ public abstract class AbstractEventView<P extends EventViewBase.Presenter> exten
|
||||
|
||||
@Override
|
||||
public void setSailorInfos(String description, String buttonLabel, String url) {
|
||||
layout.simpleInfoUi.setDescription(SafeHtmlUtils.fromString(description.replace("\n", " ")));
|
||||
layout.simpleInfoUi.setAction(buttonLabel, url);
|
||||
layout.sailorInfoUi.setDescription(SafeHtmlUtils.fromString(description.replace("\n", " ")));
|
||||
layout.sailorInfoUi.setAction(buttonLabel, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindfinderNavigations(Iterable<SpotDTO> spotData) {
|
||||
layout.windfinderWrapperUi.getStyle().clearDisplay();
|
||||
layout.windfinderUi.setSpotData(spotData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeriesNavigation(String buttonLabel, PlaceNavigation<?> placeNavigation) {
|
||||
layout.simpleInfoUi.setAction(buttonLabel, placeNavigation);
|
||||
layout.seriesNavigationoUi.setAction(buttonLabel, placeNavigation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-4
@@ -7,9 +7,12 @@
|
||||
.headerWrapper {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.windfinderWrapper {
|
||||
padding-bottom: 10px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
.windfinder {
|
||||
display: block;
|
||||
margin: 0 10px 10px;
|
||||
width: 100%;
|
||||
border-radius: .384615384615385em;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -18,8 +21,11 @@
|
||||
<div class="{style.headerWrapper}">
|
||||
<mp:eventheader.EventHeader ui:field="eventHeaderUi" />
|
||||
<mp:quickfinder.Quickfinder ui:field="quickFinderUi" />
|
||||
<mp:simpleinfoblock.SimpleInfoBlock ui:field="simpleInfoUi" />
|
||||
<sp:windfinder.WindfinderControl ui:field="windfinderUi" addStyleNames="{style.windfinder}" />
|
||||
<mp:simpleinfoblock.SimpleInfoBlock ui:field="sailorInfoUi" />
|
||||
<mp:simpleinfoblock.SimpleInfoBlock ui:field="seriesNavigationoUi" />
|
||||
<div class="{style.windfinderWrapper}" style="display:none;" ui:field="windfinderWrapperUi">
|
||||
<sp:windfinder.WindfinderControl ui:field="windfinderUi" addStyleNames="{style.windfinder}" />
|
||||
</div>
|
||||
</div>
|
||||
<g:SimplePanel ui:field="viewContentUi"></g:SimplePanel>
|
||||
</g:HTMLPanel>
|
||||
|
||||
+1
-1
@@ -30,11 +30,11 @@ public class RegattaActivity extends AbstractEventActivity<RegattaOverviewPlace>
|
||||
@Override
|
||||
protected EventViewBase initView() {
|
||||
final AbstractEventOverview view = new RegattaOverviewImpl(this, flagImageResolver);
|
||||
initSailorInfo(view);
|
||||
initSeriesNavigation(view);
|
||||
initQuickfinder(view, true);
|
||||
initWindfinderNavigations(view);
|
||||
if (!isMultiRegattaEvent()) {
|
||||
// initSailorInfo(view);
|
||||
initMedia(view);
|
||||
}
|
||||
return view;
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class HomePlacesNavigator extends AbstractPlaceNavigator {
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getMailVerifiedConfirmationNavigation() {
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.MAIL_VERIFIED));
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.MAIL_VERIFIED, null, null));
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getPasswordResettedConfirmationNavigation(String username) {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
text-decoration: none;
|
||||
vertical-align: bottom;
|
||||
padding-left: 1em;
|
||||
padding-right: 0.5em
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.windfindercontrol_text, .windfindercontrol_icon {
|
||||
display: inline-block;
|
||||
|
||||
+16
-1
@@ -86,7 +86,22 @@ public class ConfirmationPlace extends AbstractBasePlace implements HasMobileVer
|
||||
|
||||
@Override
|
||||
public String getToken(ConfirmationPlace place) {
|
||||
return place.getAction().name()+"?u="+URL.encodeQueryString(place.getName())+"&v="+URL.encodeQueryString(place.getValidationSecret());
|
||||
final StringBuilder result = new StringBuilder(place.getAction().name());
|
||||
if (place.getName() != null || place.getValidationSecret() != null) {
|
||||
result.append('?');
|
||||
if (place.getName() != null) {
|
||||
result.append("u=");
|
||||
result.append(URL.encodeQueryString(place.getName()));
|
||||
}
|
||||
if (place.getValidationSecret() != null) {
|
||||
if (place.getName() != null) {
|
||||
result.append('&');
|
||||
}
|
||||
result.append("v=");
|
||||
result.append(URL.encodeQueryString(place.getValidationSecret()));
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -748,6 +748,7 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
allEvents.clear();
|
||||
allEvents.addAll(events);
|
||||
filterTextbox.updateAll(allEvents);
|
||||
eventTable.redraw();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+3
-3
@@ -1264,7 +1264,7 @@ removeResult=Löschergebnis: {0} {1}
|
||||
uploadSuccessful=Hochladen erfolgreich
|
||||
fileUploadResult=Ergebnis des Hochladens: {0} {1}\nIm Fehlerfall bitte die Konfiguration für "Datei Speicherung" prüfen.
|
||||
removeUploadedFile=Hochgeladene Datei löschen
|
||||
showCompetitorBoatColumn=Boat des Teilnehmers anzeigen
|
||||
showCompetitorBoatColumn=Boot des Teilnehmers anzeigen
|
||||
showCompetitorSailIdColumn=Segelnummer anzeigen
|
||||
showCompetitorSailIdColumnTooltip=Zeigt die Segelnummer sowie eine Nationalitäten-Flagge oder ein Teilnehmerbild an. Ein Teilnehmerbild wird hierbei bevorzugt angzeigt, falls vorhanden. Falls auch "{0}" ausgewählt ist, werden stets beide Bilder angezeigt.
|
||||
showCompetitorShortNameColumn=Kurzen Teilnehmernamen anzeigen
|
||||
@@ -1607,8 +1607,8 @@ favoriteCompetitors=Favorisierte Teilnehmer
|
||||
favoriteBoatClasses=Favorisierte Bootsklassen
|
||||
notificationAboutNewResults=Über neue Ergebnisse informieren
|
||||
notificationAboutUpcomingRaces=Über demnächst stattfindende Rennen informieren
|
||||
currentHeelInDegree=Seitenneigung
|
||||
currentHeelInDegreeTooltip=Die aktuelle Seitenneigung in Grad
|
||||
currentHeelInDegree=Krängung
|
||||
currentHeelInDegreeTooltip=Die aktuelle Krängung in Grad
|
||||
currentPitchInDegree=Neigung
|
||||
currentPitchDegreeTooltip=Die aktuelle Neigung in Grad
|
||||
currentRideHeightInMeters=Fahrhöhe
|
||||
|
||||
+112
-1
@@ -9,10 +9,12 @@ trackedBefore=Historial de eventos rastreados
|
||||
general=General
|
||||
listRaces=Listar carreras
|
||||
listRegattas=Listar regatas
|
||||
numberPairResultsPresenter=Diagrama de dispersión
|
||||
wind=Viento
|
||||
maneuverType=Maniobra
|
||||
windPanelLabel=Este es el panel de vientos, y hasta el momento está totalmente vacío.
|
||||
refresh=Refrescar
|
||||
remove=Eliminar
|
||||
removeNumber=Eliminar ({0})
|
||||
windSource=Fuente de vientos
|
||||
dampeningInterval=Intervalo de amortiguación
|
||||
@@ -51,6 +53,7 @@ trackedRaceConnectedToSelectedRaceName=Carrera rastreada conectada al nombre de
|
||||
linkToColumn=Enlace a columna
|
||||
unlink=Quitar enlace
|
||||
leaderboardName=Nombre de tabla de clasificación
|
||||
cancel=Cancelar
|
||||
pleaseEnterAName=Indique un nombre
|
||||
pleaseEnterABoatClass=Indique una clase de embarcación
|
||||
discardRacesFromHowManyStartedRacesOn=Descartar un inicio de carrera más con cuántas carreras iniciadas
|
||||
@@ -62,6 +65,7 @@ startingFromNumberOfRaces=Empezando por cuántas carreras
|
||||
renameLeaderboard=Cambiar nombre de tabla de clasificación
|
||||
addColumnToLeaderboard=Añadir columna a tabla de clasificación
|
||||
pleaseEnterNameForNewRaceColumn=Indique un nombre para la nueva columna de carrera
|
||||
ok=OK
|
||||
medalRace=Medal Race
|
||||
renameRace=Cambiar nombre de carrera
|
||||
openSelectedLeaderboard=Abrir tabla de clasificación seleccionada
|
||||
@@ -85,6 +89,7 @@ sapSailingAnalytics=Sailing Analytics
|
||||
leaderboard=Tabla de clasificación
|
||||
leaderboards=Tablas de clasificación
|
||||
leaderboardSettings=Opciones de tabla de clasificación
|
||||
settings=Opciones
|
||||
selectAtLeastOneLegDetail=Seleccione al menos un detalle de tramo
|
||||
currentSpeedOverGroundInKnots=SOG (speed over ground)
|
||||
currentSpeedOverGroundInKnotsTooltip=Velocidad actual sobre el fondo.
|
||||
@@ -168,6 +173,7 @@ tacks=Bordadas
|
||||
jibes=Trasluchadas
|
||||
penaltyCircles=Círculos de penalización
|
||||
medalRaceIsNull=Valor de regata final no permitido
|
||||
configuration=Configuración
|
||||
maneuverTypes=Maniobras
|
||||
chooseChart=Seleccionar gráfico
|
||||
distanceTraveled=Distancia viajada
|
||||
@@ -185,11 +191,13 @@ secondsPerNauticalMileUnit=s/NM
|
||||
metersUnit=m
|
||||
millimetersUnit=mm
|
||||
degreesUnit=°
|
||||
close=Cerrar
|
||||
compareCompetitors=Comparar competidores
|
||||
description=Descripción
|
||||
sailNumber=Número de vela
|
||||
country=País
|
||||
no3LetterCodes=No es posible encontrar los códigos IOC de 3 letras.
|
||||
add=Añadir
|
||||
delete=Borrar
|
||||
showCharts=Mostrar gráficos
|
||||
raceWithThisNameAlreadyExists=Ya existe una carrera con este nombre.
|
||||
@@ -261,6 +269,7 @@ printHint=Imprime la versión aplicada
|
||||
blockedApplyButton=Los competidores registrados difieren de los competidores de la lista de emparejamientos
|
||||
multiplierInfo=Multiplica los flights y los crea uno junto a otro de modo que sea posible una competición con menos modificaciones de embarcación.
|
||||
noPairingListAvailable=La función de impresión solo está disponible si ya se han aplicado las listas de emparejamientos a los registros de carrera de las clasificaciones seleccionadas.
|
||||
settingsForComponent=Opciones para {0}
|
||||
noEventsFound=No se han encontrado eventos
|
||||
noEventSelected=Ningún evento seleccionado
|
||||
noLeaderboardsFound=No se han encontrado tablas de clasificación
|
||||
@@ -298,6 +307,8 @@ leaderboardGroup=Grupo de tablas de clasificación
|
||||
pleaseEnterNonEmptyDescription=Indique una descripción no vacía
|
||||
groupWithThisNameAlreadyExists=Ya existe un grupo de tablas de clasificación con este nombre.
|
||||
detailsOfLeaderboardGroup=Detalles del grupo de tablas de clasificación
|
||||
edit=Editar
|
||||
save=Grabar
|
||||
abort=Detener
|
||||
noLeaderboardGroupWithNameFound=No se ha encontrado ningún grupo de tablas de clasificación con el nombre {0}
|
||||
overview=Resumen
|
||||
@@ -332,6 +343,7 @@ degreesShort=grados
|
||||
untracked=No rastreado
|
||||
delayForLiveMode=Retraso para modo en directo
|
||||
notAvailable=No disponible
|
||||
details=Detalles
|
||||
noGroupSelected=Ningún grupo seleccionado
|
||||
combinedWindSourceTypeName=Combinado
|
||||
legMiddleWindSourceTypeName=Mitad de tramo
|
||||
@@ -413,6 +425,7 @@ simulateAsLiveRace=Simular como carrera en directo
|
||||
simulateWithOffset=Offset antes de inicio en minutos:
|
||||
boatClassDoesNotMatchSelectedRegatta=Las carreras seleccionadas contienen clases de embarcación distintas de la clase ''''{0}'''' de la regata seleccionada. No se cargará ninguna carrera.
|
||||
regattaExistForSelectedBoatClass=Hay al menos una regata para las clases de embarcación seleccionadas. ¿Realmente desea crear regata(s) por defecto para esta(s) carrera(s)?
|
||||
reload=Recargar
|
||||
addRegatta=Añadir regata...
|
||||
importRegattas=Importar regatas...
|
||||
exchangeName=Intercambiar nombre
|
||||
@@ -634,6 +647,7 @@ totalNetPointsColumnTooltip=El total de puntos netos de un competidor de la rega
|
||||
windData=Datos de vientos
|
||||
gpsData=Datos de GPS
|
||||
status=Status
|
||||
noDataFound=No se han encontrado datos
|
||||
displayName=Visualizar nombre
|
||||
histogram=Histograma
|
||||
numberOfDataPoints=Número de puntos de datos
|
||||
@@ -881,9 +895,12 @@ legType=Tipo de tramo
|
||||
sailID=Número de vela
|
||||
seriesLeaderboard=Tabla de clasificación de serie
|
||||
regattaLeaderboards=Clasificaciones de regata
|
||||
clearSelection=Borrar selección
|
||||
running=En ejecución
|
||||
runAsSubstantive=Ejecutar
|
||||
done=Hecho
|
||||
lastFinished=Último que ha terminado
|
||||
run=Ejecutar
|
||||
times=tiempos
|
||||
dataAmount=Cantidad de datos
|
||||
averageCleanedServerTime=∅ Tiempo de servidor limpio
|
||||
@@ -907,8 +924,12 @@ selectSheet=Seleccionar hoja
|
||||
cleanedServerTime=Tiempo de servidor limpio
|
||||
overallTime=Tiempo total
|
||||
cleanedOverallTime=Tiempo global limpio
|
||||
dataMiningResult=Resultado de minería de datos
|
||||
groupBy=Agrupar por
|
||||
statisticToCalculate=Calcular estadística
|
||||
queryResultsChartSubtitle=Se ha trabajado en {0} entradas de datos en {1} segundos
|
||||
noQuerySelected=Ninguna consulta seleccionada
|
||||
runAutomatically=Ejecutar automáticamente
|
||||
windImport_Upload=Cargar
|
||||
windImport_Title=Importar viento desde expedición
|
||||
windImport_BoatId=ID de embarcación:
|
||||
@@ -938,9 +959,14 @@ raceTimeTooltip=Tiempo total recorrido en esta carrera, se empieza a medir cuand
|
||||
raceTimeDownwindTooltip=Tiempo total de empopada recorrido en esta carrera
|
||||
raceTimeReachingTooltip=Tiempo total de alcance recorrido en esta carrera
|
||||
raceTimeUpwindTooltip=Tiempo total de ceñida recorrido en esta carrera
|
||||
noStatisticSelectedError=No se ha seleccionado ninguna estadística para calcular
|
||||
noCustomGrouperScriptTextError=El script de grupo está vacío
|
||||
noDimensionToGroupBySelectedError=No se ha seleccionado ninguna dimensión para agrupar
|
||||
noGrouperSelectedError=No se ha seleccionado ningún tipo de agrupador
|
||||
noDataRetrieverChainDefinitonSelectedError=No se ha seleccionado ningún recuperador de datos
|
||||
queryNotValidBecause=No se puede hacer ninguna consulta porque
|
||||
dataMining=Minería de datos
|
||||
errorRunningDataMiningQuery=Se ha producido un error al ejecutar la consulta
|
||||
hideToolbar=Ocultar barra de herramientas
|
||||
showSeriesLeaderboards=Mostrar tablas de clasificación de las series
|
||||
showOverallLeaderboard=Mostrar tabla de clasificación general
|
||||
@@ -963,6 +989,7 @@ id=ID
|
||||
allowReload=Permitir recarga
|
||||
compress=Comprimir
|
||||
compressTooltip=Utilizar solamente si la instancia del servidor de exportación funciona al menos con la confirmación 0fbf6071dea125bec4a56dee55d61c99def4a62e.
|
||||
queryRunner=Ejecutor de la consulta
|
||||
rerunQueryAfterRefresh=Volver a ejecutar la consulta después de actualizar
|
||||
refreshIntervalMustntBeEmpty=El intervalo de actualización no debe estar en blanco
|
||||
selectionTables=Tablas de selección
|
||||
@@ -1047,7 +1074,12 @@ TWATooltip=Ángulo entre la dirección de los competidores y el viento
|
||||
TWA=Ángulo real del viento
|
||||
showBoatClassChartsLabel=También puede visualizar el diagrama global para las clases de embarcación disponibles.
|
||||
showDiagram=Mostrar diagrama
|
||||
runAutomaticallyTooltip=Ejecute la consulta automáticamente después de modificar, por ejemplo, la estadística o la agrupación.
|
||||
rerunQueryAfterRefreshTooltip=Vuelve a ejecutar la consulta después de que se hayan refrescado las tablas.
|
||||
queryDefinitionProvider=Proveedor de definición de consultas
|
||||
statisticProvider=Proveedor de estadísticas
|
||||
calculateThe=Calcular
|
||||
groupingProvider=Proveedor de agrupación
|
||||
releaseNotes=Historial de noticias y lanzamientos
|
||||
hasSplitFleetContiguousScoring=Dividir flotas puntuadas de forma contigua
|
||||
addRaceLogTracker=Añadir rastreador de registro de carrera
|
||||
@@ -1205,6 +1237,7 @@ showAll=Mostrar todo
|
||||
raceVisibilityColumn=Visibilidad
|
||||
enterCarryValueFor=Introducir puntos acumulados para el competidor {0}
|
||||
advanced=Avanzado
|
||||
basedOn=Basado en
|
||||
retrieveWith=Recuperar con
|
||||
mappingDetails=Detalles de asignación
|
||||
deviceMappingQrCodeExplanation=Si utiliza la aplicación de rastreo, también puede añadir la asignación de dispositivos seleccionando un competidor/marca, definiendo las fechas de inicio y fin y escaneando este código QR
|
||||
@@ -1215,6 +1248,10 @@ enterImageURL=Indicar URL de imagen...
|
||||
enterVideoURL=Indicar URL de vídeo...
|
||||
enterSponsorImageURL=Indicar URL de imagen de patrocinador...
|
||||
enterRaceName=Indicar nombre de carrera...
|
||||
serverError=Se ha producido un error al intentar contactar con el servidor. Compruebe la conexión de red e inténtelo de nuevo.
|
||||
remoteProcedureCall=Llamada de procedimiento remoto
|
||||
serverReplies=Servidor responde
|
||||
errorCommunicatingWithServer=Error al comunicar con el servidor
|
||||
userManagement=Gestión de usuarios
|
||||
regattaStructureImport=Importación de la estructura de regata
|
||||
filteredBy=Filtrado por
|
||||
@@ -1242,6 +1279,7 @@ noFleetsDefined=Ninguna flota definida
|
||||
successfullyCreatedRegattas=Regatas creadas con éxito
|
||||
errorTryingToRegisterRacesForTracking=Error al intentar registrar carreras {0} para rastreo: {1}. Compruebe sintaxis URI en directo/grabada.
|
||||
errorDeterminingPolarAvailability=Error al determinar la disponibilidad de datos polares / VPP para la carrera {0}: {1}
|
||||
error=Error
|
||||
fileStorage=Almacenamiento de archivos
|
||||
active=Activo
|
||||
scoringSchemeHighPointEssOverallDescription=Calificación en puntos. El ganador de una prueba obtiene 10 puntos; el segundo, 9 puntos, etc. Si hay un empate en la serie de Extreme Sailing, el empate se resuelve a favor del competidor que ha ganado más pruebas. Si aún persiste el empate, se utiliza el resultado de la última prueba.
|
||||
@@ -1284,6 +1322,7 @@ showCompetitorFullNameColumn=Nombre completo del competidor
|
||||
alwaysShowCompetitorNationalityColumn=Siempre mostrar la nacionalidad del competidor
|
||||
alwaysShowCompetitorNationalityColumnTooltip=Muestra ambos, las banderas de país así como las imágenes de competidor, si están disponibles.
|
||||
loadingDimensionValues=Cargando valores de dimensión
|
||||
runningQuery=Ejecutando consulta
|
||||
inviteBuoyTenders=Invitar a balizadores
|
||||
orMultipleEmails=o varios correos electrónicos separados por una coma
|
||||
courseOverGroundTrueDegreesTooltip=Regata sobre el fondo (Course Over Ground) en grados
|
||||
@@ -1291,6 +1330,11 @@ courseOverGroundTrueDegrees=COG
|
||||
distanceIncludingGateStartInMeters=Distancia (con inicio de puerta de salida)
|
||||
distanceTraveledIncludingGateStartTooltip=Distancia recorrida desde el inicio hasta el final del tramo\o hasta la fecha y hora actual si no se ha acabado el tramo.\nSi el tramo incluye un inicio de puerta de salida, la distancia desde el extremo hasta la posición inicial se incluye\n para que puedan compararse los competidores aunque hayan empezado en tiempos diferentes.
|
||||
raceDistanceTraveledIncludingGateStartTooltip=Distancia recorrida desde el inicio hasta el final de la carrera\o hasta la fecha y hora actual si no se ha acabado la carrera. Para el inicio de la puerta de salida, la distancia desde el extremo hasta la posición inicial se incluye\n para que puedan compararse los competidores aunque hayan empezado en tiempos diferentes.
|
||||
results=Resultados
|
||||
groupName=Nombre de grupo
|
||||
valueAscending=Valor (ascendente)
|
||||
valueDescending=Valor (descendente)
|
||||
sortBy=Ordenado por
|
||||
dashboardHeader=Dashboard
|
||||
dashboardNoWindBotAvailableHeader=Wind Bot no está disponible
|
||||
dashboardNoWindBotAvailableMessage=Para obtener los datos de viento en directo a partir de unidades de medida de viento, asegúrese de que Wind Bot está activado y contectado con SAP Sailing Analytics.
|
||||
@@ -1326,12 +1370,16 @@ dashboardRCBoat=Barco RC
|
||||
fixedMarkPassing=(fijado)
|
||||
suppressedMarkPassing=(suprimido)
|
||||
windUp=Viento al norte (mostrar viento de la parte superior del mapa)
|
||||
filterBy=Filtrar por
|
||||
currentFilterSelection=Seleccion de filtro actual
|
||||
notCapableOfGeneratingACodeForIdentifier=No sé generar un código para este identificador.
|
||||
serverUrl=URL del servidor
|
||||
rotatedFromTrueNorth=Ha rotado {0} grados desde el norte real.
|
||||
clickToToggleWindUp=Golpe/clic para alternar entre visualización mapa viento al norte y norte arriba
|
||||
clickToToggleWindStreamlets=Golpe/clic para mostrar u ocultar corrientes de viento
|
||||
startLineToFirstMarkTriangle=Inicio a la primera marca ({0} m)
|
||||
dataMiningComponentsHaveBeenUpdated=Los componentes de minería de datos se han actualizado
|
||||
dataMiningComponentsNeedReloadDialogMessage=Pulse Recargar para volver a cargar los componentes ahora. De este modo, se descartarán los datos visualizados en ese momento y se ejecutará una consulta por defecto.\nHaga clic en «Cerrar» para no hacer nada. La minería de datos no funcionará correctamente hasta que se hayan vuelto a cargar los componentes.
|
||||
noDataForEvent=Todavía no hay datos para el evento.
|
||||
countriesCount={0,number} países
|
||||
countriesCount[one]={0,number} país
|
||||
@@ -1429,7 +1477,15 @@ noFinishedRaces=Todavía no ha finalizado ninguna carrera
|
||||
racesOverview=Resumen de carreras
|
||||
listFormatLabel=Formato de lista
|
||||
competitionFormatLabel=Formato de competición
|
||||
empty=Vacío
|
||||
runAQuery=Realice una consulta
|
||||
latestRegattaStandings=Últimas posiciones de la regata
|
||||
plainText=Texto sin formato
|
||||
columnChart=Gráfico de columnas
|
||||
columnChartWithErrorBars=Gráfico de columnas con barras de error
|
||||
choosePresentation=Seleccionar presentación
|
||||
cantDisplayDataOfType=No se pueden mostrar datos del tipo {0}
|
||||
shownDecimals=Decimales mostrados
|
||||
openFullscreenView=Abrir vista de pantalla completa
|
||||
closeFullscreenView=Cerrar vista de pantalla completa
|
||||
videosCount={0,number} vídeos
|
||||
@@ -1439,8 +1495,15 @@ photosCount[one]={0,number} foto
|
||||
eventsHaveTakenPlace=Han tenido lugar {0} eventos
|
||||
eventsHaveTakenPlace[one]=Ha tenido lugar un evento
|
||||
raceOffice=Oficina de carrera
|
||||
analyze=Analizar
|
||||
dataMiningSettings=Opciones de minería de datos
|
||||
multiResultsPresenter=Presentador de resultados múltiples
|
||||
plainResultsPresenter=Presentador de resultados simples
|
||||
resultsChart=Gráfico de resultados
|
||||
tabbedResultsPresenter=Presentador de resultados por pestañas
|
||||
polarResultsPresenter=Presentador de resultados de coordenadas polares
|
||||
maneuverSpeedDetailsResultsPresenter=Presentador de resultados detallados de velocidad de maniobra
|
||||
dataMiningRetrieval=Recuperación de datos
|
||||
actionWatch=Observar
|
||||
actionAnalyze=Analizar
|
||||
denoteAllRacesForRaceLogTrackingShorctut=Acceso directo para indicar todas las carreras para un rastreo de registro de carrera
|
||||
@@ -1456,8 +1519,24 @@ defaultName=Por defecto
|
||||
exampleTextForName=Su nombre aparece como:
|
||||
flightsCount={0,number} flights
|
||||
flightsCount[one]={0,number} flight
|
||||
viewQueryDefinition=Ver definición de consulta
|
||||
queryDefinitionViewer=Visor de definición de consulta
|
||||
groupAverageAscending=Promedio de grupo (ascendente)
|
||||
groupAverageDescending=Promedio de grupo (descendente)
|
||||
groupMedianAscending=Mediana de grupo (ascendente)
|
||||
groupMedianDescending=Mediana de grupo (descendente)
|
||||
resultsFoundForSearch={0,number} resultados encontrados para ''''{1}''''
|
||||
resultsFoundForSearch[one]={0,number} resultado encontrado para ''''{1}''''
|
||||
runPredefinedQuery=Ejecutar consulta predefinida
|
||||
selectPredefinedQuery=Seleccionar consulta predefinida
|
||||
predefinedQueryRunner=Programa de ejecución de consulta predefinida
|
||||
developerOptions=Opciones de desarrollador
|
||||
copyToClipboard=Copiar a portapapeles
|
||||
code=Código
|
||||
useClassGetName=Utilizar Class.getName() para nombres de tipo
|
||||
useClassGetNameTooltip=Más resistente frente a modificaciones en la base de código, pero el fragmento de código se puede utilizar solamente en el ámbito donde estén disponibles las clases.
|
||||
useStringLiterals=Utilizar literales de cadena para los nombres de tipo
|
||||
useStringLiteralsTooltip=El fragmento de código puede utilizarse en todas las ubicaciones, pero se romperá si se modifica la base de código.
|
||||
errorLoadingDataWithTryAgain=Error al cargar los datos. Inténtelo de nuevo más tarde.
|
||||
addGalleryPhoto=Añadir foto de galería
|
||||
addStageImage=Añadir imagen de etapa
|
||||
@@ -1477,6 +1556,7 @@ warningForDisabledCompetitors=Los siguientes competidores no se pueden registrar
|
||||
competitorToolTipMessage={0} ya ha sido asignado a la flota {2} en la carrera {3} y, por consiguiente, no se puede asignar a la flota {1} de la misma carrera
|
||||
addMarkToRegatta=Añadir marca a regata
|
||||
selectALeaderboardGroup=Seleccione un grupo de tablas de clasificación...
|
||||
pleaseSelect=Seleccione
|
||||
requiresValidRegatta=Esta página requiere una regata, una columna de carreras y un nombre de flota válidos para identificar la regata que se desea mostrar.
|
||||
couldNotObtainRace=No se ha podido obtener la regata con el nombre {1} para la flota {2} para una regata con el nombre {0}: {3}
|
||||
errorTryingToCreateEmbeddedMap=Error al intentar crear el mapa incrustado: {0}
|
||||
@@ -1756,9 +1836,30 @@ eventRegattaHeaderLegendGpsNo=No hay datos de rastreo
|
||||
eventRegattaHeaderLegendWindNo=No hay datos de viento
|
||||
eventRegattaHeaderLegendVideoNo=No hay transmisiones de vídeo
|
||||
eventRegattaHeaderLegendAudioNo=No hay transmisiones de audio
|
||||
angleInDegree=Ángulo en grado
|
||||
angleInRadian=Ángulo en radián
|
||||
centralAngleInRadian=Ángulo central en radián
|
||||
centralAngleInDegree=Ángulo central en grado
|
||||
kilometers=Kilómetros
|
||||
meters=Metros
|
||||
nauticalMiles=Millas náuticas
|
||||
seaMiles=Millas marinas
|
||||
geographicalMiles=Millas geográficas
|
||||
days=Días
|
||||
hours=Horas
|
||||
minutes=Minutos
|
||||
seconds=Segundos
|
||||
milliseconds=Milisegundos
|
||||
floatNumber=Flotador
|
||||
integer=Entero
|
||||
appendResult=Resultado de estructura append
|
||||
sampleColor=Muestra de color
|
||||
sharedSettingsLink=Enlace con opciones
|
||||
leaderboardPage=Página de clasificación
|
||||
makeDefault=Establecer como predeterminado
|
||||
makeDefaultInProgress=En curso...
|
||||
settingsSavedMessage=Sus opciones actuales se han definido correctamente como estándar
|
||||
settingsSaveErrorMessage=Se ha producido un error durante la definición de sus opciones como estándar
|
||||
showLiveNow=Mostrar "En directo ahora"
|
||||
useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Utilice solo una "Inferencia de hora de inicio" y "Control de rastreo de horas de inicio y de fin"
|
||||
unknownLeaderboardType=Tipo de tabla de clasificación {0} desconocido
|
||||
@@ -1770,13 +1871,17 @@ raceRankShort=Posición de carrera
|
||||
showRaceRankColumn=Mostrar posición de carrera
|
||||
estimatedDistance=Distancia estimada
|
||||
estimatedTime=Hora estimada
|
||||
nothingUpcoming=Actualmente no existen más carreras planificadas
|
||||
nothingUpcoming=No existen más carreras que comiencen pronto
|
||||
noUpcomingRaceDataAvailable=Sin datos disponibles de próxima carrera
|
||||
reallyRemoveSeries=¿Desea realmente eliminar la serie "{0}"? Nota: todos los logs de las columnas de carrera anexas también se eliminarán de forma permanente.
|
||||
settingsId=ID de opciones
|
||||
documentSettingsId=ID de opciones de documento
|
||||
settingsForId=Opciones para ID ''''{0}''''
|
||||
userProfileSettingsTabDescription=Las opciones del usuario se generan mediante los diálogos de opciones que se encuentran en varios puntos de la página. Esta vista muestra todas sus opciones agrupadas de una manera técnica para los usuarios expertos. Tenga en cuenta que las entradas eliminadas no se pueden restablecer, por lo que tenga precaución al utilizarlas.
|
||||
resetToDefault=Reinicializar a valores por defecto
|
||||
resetToDefaultInProgress=Reinicializando...
|
||||
settingsRemoved=Opciones por defecto restablecidas
|
||||
settingsRemovedError=No se han podido restablecer las opciones por defecto
|
||||
userSettingsFilter=Filtro de opciones
|
||||
requiresRegattaRaceAndLeaderboard=Esta página requiere un nombre de regata, un nombre de carrera y un nombre de tabla de clasificación válidos.
|
||||
couldNotFindRaceInRegatta=No se ha podido obtener la carrera con el nombre {0} para la regata con el nombre {1}
|
||||
@@ -1808,6 +1913,7 @@ errorFetchingDimensionData=Error al obtener los valores de dimensión de {0} : {
|
||||
errorFetchingStatistics=Error al obtener las estadísticas disponibles desde el servidor: {0}
|
||||
errorFetchingAggregators=Error al obtener los agregadores disponibles desde el servidor: {0}
|
||||
errorLoadingDataRetrieverChainDefinitions=Error al recuperar las DataRetrieverChainDefinitions disponibles: {0}
|
||||
errorFetchingComponentsChangedTimepoint=Error al obtener la fecha modificada de los componentes a partir del servidor: {0}
|
||||
errorRunningQuery=Error al ejecutar la consulta: {0}
|
||||
errorReadingWindFixes=Error al leer las correcciones de viento {0}
|
||||
errorAddingWindFixForRace=Error al añadir una corrección de viento para la carrera {0}: {1}
|
||||
@@ -1881,6 +1987,11 @@ minimumRideHeightInMetersTooltip=La altura de marcha mínima en metros requerida
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSeconds=Duración mínima entre apéndice(s) de foil
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSecondsTooltip=Si no está en blanco y el tiempo entre dos apéndices de foil adyacentes es inferior, aquellos apéndices de foil adyacentes se fusionarán en uno solo.
|
||||
needToProvideValidMinimumRideHeight=Requiere proporcionar un valor de altura de marcha mínimo válido en metros.
|
||||
dataMiningErrorMargins=Márgenes de error
|
||||
elements={0} elementos
|
||||
chooseDifferentDimensionTitle=Seleccione una dimensión diferente
|
||||
chooseDifferentDimensionMessage=Seleccione una dimensión diferente para agrupar resultados
|
||||
pleaseSelectADimension=Seleccione una dimensión
|
||||
currentPortDaggerboardRake=Inclinación de la orza de babor
|
||||
currentPortDaggerboardRakeTooltip=La inclinación actual de la orza de babor
|
||||
currentStbdDaggerboardRake=Inclinación de la orza de estribor
|
||||
|
||||
+112
-1
@@ -9,10 +9,12 @@ trackedBefore=Historique des manifestations suivies
|
||||
general=Généralités
|
||||
listRaces=Lister courses
|
||||
listRegattas=Lister régates
|
||||
numberPairResultsPresenter=Concentration points mesure
|
||||
wind=Vent
|
||||
maneuverType=Manœuvre
|
||||
windPanelLabel=Ceci est le panneau des mesures du vent, vide pour l''instant.
|
||||
refresh=Actualiser
|
||||
remove=Supprimer
|
||||
removeNumber=Supprimer ({0})
|
||||
windSource=Source du vent
|
||||
dampeningInterval=Intervalle d''atténuation
|
||||
@@ -51,6 +53,7 @@ trackedRaceConnectedToSelectedRaceName=Course suivie liée au nom de course sél
|
||||
linkToColumn=Lier à la colonne
|
||||
unlink=Annuler Lier
|
||||
leaderboardName=Nom du palmarès
|
||||
cancel=Annuler
|
||||
pleaseEnterAName=Saisissez un nom.
|
||||
pleaseEnterABoatClass=Saisissez une catégorie de bateau.
|
||||
discardRacesFromHowManyStartedRacesOn=Éliminez une course de plus en commençant au nombre de courses déjà lancées.
|
||||
@@ -62,6 +65,7 @@ startingFromNumberOfRaces=Début au nombre de courses
|
||||
renameLeaderboard=Renommer palmarès
|
||||
addColumnToLeaderboard=Ajouter colonne à palmarès
|
||||
pleaseEnterNameForNewRaceColumn=Saisissez un nom pour la nouvelle colonne de course.
|
||||
ok=OK
|
||||
medalRace=Course médaillée
|
||||
renameRace=Renommer course
|
||||
openSelectedLeaderboard=Ouvrir le palmarès sélectionné
|
||||
@@ -85,6 +89,7 @@ sapSailingAnalytics=Sailing Analytics
|
||||
leaderboard=Palmarès
|
||||
leaderboards=Palmarès
|
||||
leaderboardSettings=Options du palmarès
|
||||
settings=Options
|
||||
selectAtLeastOneLegDetail=Sélectionnez au moins un détail de portion de parcours.
|
||||
currentSpeedOverGroundInKnots=Vf
|
||||
currentSpeedOverGroundInKnotsTooltip=La vitesse fond actuelle.
|
||||
@@ -168,6 +173,7 @@ tacks=Virements
|
||||
jibes=Changements d''amure
|
||||
penaltyCircles=Tours de pénalité
|
||||
medalRaceIsNull=Valeur de course à la médaille non autorisée
|
||||
configuration=Configuration
|
||||
maneuverTypes=Manœuvres
|
||||
chooseChart=Sélectionner graphique
|
||||
distanceTraveled=Distance parcourue
|
||||
@@ -185,11 +191,13 @@ secondsPerNauticalMileUnit=s/NM
|
||||
metersUnit=m
|
||||
millimetersUnit=mm
|
||||
degreesUnit=°
|
||||
close=Fermer
|
||||
compareCompetitors=Comparer concurrents
|
||||
description=Description
|
||||
sailNumber=Numéro de voile
|
||||
country=Pays
|
||||
no3LetterCodes=Codes CIO à trois lettres introuvables
|
||||
add=Ajouter
|
||||
delete=Supprimer
|
||||
showCharts=Afficher graphiques
|
||||
raceWithThisNameAlreadyExists=Une course de ce nom existe déjà.
|
||||
@@ -261,6 +269,7 @@ printHint=Imprime la version appliquée
|
||||
blockedApplyButton=Le nombre de concurrents inscrits ne correspond pas au nombre de concurrents de la liste d''appariement.
|
||||
multiplierInfo=Multipliez les flights et créez-les les uns après les autres pour obtenir une compétition avec le moins de bateaux possible.
|
||||
noPairingListAvailable=La fonction d''impression est uniquement disponible lorsqu''une liste d''appariement a déjà été appliquée aux journaux de course des palmarès sélectionnés.
|
||||
settingsForComponent=Options pour {0}
|
||||
noEventsFound=Aucune manifestation trouvée
|
||||
noEventSelected=Aucune manifestation sélectionnée
|
||||
noLeaderboardsFound=Aucun palmarès trouvé
|
||||
@@ -298,6 +307,8 @@ leaderboardGroup=Groupe de palmarès
|
||||
pleaseEnterNonEmptyDescription=Saisissez une description (ne pas laisser vide).
|
||||
groupWithThisNameAlreadyExists=Un groupe de palmarès de ce nom existe déjà.
|
||||
detailsOfLeaderboardGroup=Détails du groupe de palmarès
|
||||
edit=Modifier
|
||||
save=Enregistrer
|
||||
abort=Abandonner
|
||||
noLeaderboardGroupWithNameFound=Aucun groupe de palmarès ayant pour nom {0} n''a été trouvé.
|
||||
overview=Synthèse
|
||||
@@ -332,6 +343,7 @@ degreesShort=deg
|
||||
untracked=Non suivi
|
||||
delayForLiveMode=Décalage pour mode en direct
|
||||
notAvailable=Non disponible
|
||||
details=Détails
|
||||
noGroupSelected=Aucun groupe sélectionné
|
||||
combinedWindSourceTypeName=Combiné
|
||||
legMiddleWindSourceTypeName=Milieu de la portion de parcours
|
||||
@@ -413,6 +425,7 @@ simulateAsLiveRace=Simulation de course en direct
|
||||
simulateWithOffset=Décalage avant le départ (en minutes) :
|
||||
boatClassDoesNotMatchSelectedRegatta=Les courses sélectionnées contiennent des catégories de bateaux qui ne sont pas identiques à la catégorie de bateau "{0}" de la régate sélectionnée. Aucune course ne sera chargée.
|
||||
regattaExistForSelectedBoatClass=Il existe au moins une régate pour les catégories de bateaux sélectionnées. Voulez-vous vraiment créer une (des) régate(s) pour cette (ces) course(s) ?
|
||||
reload=Recharger
|
||||
addRegatta=Ajouter régate...
|
||||
importRegattas=Importer régates...
|
||||
exchangeName=Nom d''échange
|
||||
@@ -634,6 +647,7 @@ totalNetPointsColumnTooltip=Total net des points d''un concurrent dans la régat
|
||||
windData=Données de vent
|
||||
gpsData=Données GPS
|
||||
status=Statut
|
||||
noDataFound=Aucune donnée trouvée
|
||||
displayName=Afficher nom
|
||||
histogram=Histogramme
|
||||
numberOfDataPoints=Nombre de points de données
|
||||
@@ -881,9 +895,12 @@ legType=Type de portion de parcours
|
||||
sailID=Numéro de voile
|
||||
seriesLeaderboard=Palmarès de la série
|
||||
regattaLeaderboards=Palmarès de la régate
|
||||
clearSelection=Réinitialiser sélection
|
||||
running=En cours d''exécution
|
||||
runAsSubstantive=Exécuter
|
||||
done=Terminé
|
||||
lastFinished=Fin de dernière exécution
|
||||
run=Exécuter
|
||||
times=durées
|
||||
dataAmount=Volume de données
|
||||
averageCleanedServerTime=∅ Durée de nettoyage du serveur
|
||||
@@ -907,8 +924,12 @@ selectSheet=Sélectionner fiche
|
||||
cleanedServerTime=Durée de nettoyage du serveur
|
||||
overallTime=Durée globale
|
||||
cleanedOverallTime=Durée globale de nettoyage
|
||||
dataMiningResult=Résultat d''exploration de données
|
||||
groupBy=Regrouper par
|
||||
statisticToCalculate=Calculer statistiques
|
||||
queryResultsChartSubtitle={0} entrées de données analysées en {1} secondes
|
||||
noQuerySelected=Aucune requête sélectionnée
|
||||
runAutomatically=Exécuter automatiquement
|
||||
windImport_Upload=Charger
|
||||
windImport_Title=Importer vent à partir de Expedition
|
||||
windImport_BoatId=N° du bateau :
|
||||
@@ -938,9 +959,14 @@ raceTimeTooltip=Durée de navigation totale dans cette course, chronométrée à
|
||||
raceTimeDownwindTooltip=Durée totale de navigation vent arrière dans cette course
|
||||
raceTimeReachingTooltip=Durée totale de navigation jusqu''à l''arrivée dans cette course
|
||||
raceTimeUpwindTooltip=Durée totale de navigation dans le lit du vent dans cette course
|
||||
noStatisticSelectedError=Aucune statistique à calculer sélectionnée
|
||||
noCustomGrouperScriptTextError=Script de regroupement vide
|
||||
noDimensionToGroupBySelectedError=Aucune dimension sélectionnée pour le regroupement
|
||||
noGrouperSelectedError=Aucun type de regroupement sélectionné
|
||||
noDataRetrieverChainDefinitonSelectedError=Aucun récupérateur de données sélectionné
|
||||
queryNotValidBecause=Aucune requête possible dû à
|
||||
dataMining=Exploration de données
|
||||
errorRunningDataMiningQuery=Une erreur s''est produite lors de l''exécution de la requête.
|
||||
hideToolbar=Masquer barre d''outils
|
||||
showSeriesLeaderboards=Afficher palmarès de la série
|
||||
showOverallLeaderboard=Afficher palmarès général
|
||||
@@ -963,6 +989,7 @@ id=ID
|
||||
allowReload=Autoriser rechargement
|
||||
compress=Comprimer
|
||||
compressTooltip=Utiliser seulement si l''instance de serveur d''exportation \ns''exécute au moins avec le commit 0fbf6071dea125bec4a56dee55d61c99def4a62e.
|
||||
queryRunner=Outil d''exécution de requêtes
|
||||
rerunQueryAfterRefresh=Exécuter la requête de nouveau après l''actualisation
|
||||
refreshIntervalMustntBeEmpty=L''intervalle d''actualisation ne doit pas être vide.
|
||||
selectionTables=Tables de sélection
|
||||
@@ -1047,7 +1074,12 @@ TWATooltip=L''angle entre la direction du concurrent et le vent.
|
||||
TWA=Angle du vent réel
|
||||
showBoatClassChartsLabel=Vous pouvez également afficher le diagramme global pour les catégories de bateau disponibles.
|
||||
showDiagram=Afficher diagramme
|
||||
runAutomaticallyTooltip=Exécutez la requête automatiquement, par exemple après avoir modifié les statistiques ou le regroupement.
|
||||
rerunQueryAfterRefreshTooltip=Réexécute la requête après l''actualisation des tables.
|
||||
queryDefinitionProvider=Fournisseur de définitions de requêtes
|
||||
statisticProvider=Fournisseur de statistiques
|
||||
calculateThe=Calculer le/la
|
||||
groupingProvider=Fournisseur de regroupements
|
||||
releaseNotes=Historique de versions et nouveautés
|
||||
hasSplitFleetContiguousScoring=Les flottes divisées ont obtenu des scores contigus.
|
||||
addRaceLogTracker=Ajouter tracker de journal de course
|
||||
@@ -1205,6 +1237,7 @@ showAll=Afficher tout
|
||||
raceVisibilityColumn=Visibilité
|
||||
enterCarryValueFor=Saisissez les points accumulés par le concurrent {0}.
|
||||
advanced=Avancé
|
||||
basedOn=basé sur
|
||||
retrieveWith=Récupérer avec
|
||||
mappingDetails=Détails du mappage
|
||||
deviceMappingQrCodeExplanation=Si vous utilisez l''application de suivi, vous pouvez également ajouter le mappage de l''appareil en sélectionnant un concurrent/une marque, en définissant des heures de départ et d''arrivée et en scannant ce code QR.
|
||||
@@ -1215,6 +1248,10 @@ enterImageURL=Saisissez l''URL de l''image...
|
||||
enterVideoURL=Saisissez l''URL de la vidéo...
|
||||
enterSponsorImageURL=Saisissez l''URL de l''image du sponsor...
|
||||
enterRaceName=Saisissez le nom du parcours...
|
||||
serverError=Une erreur s''est produite lors de la tentative de contact du serveur. Vérifiez la connexion réseau et réessayez.
|
||||
remoteProcedureCall=Procédure d''appel distante
|
||||
serverReplies=Réponses du serveur
|
||||
errorCommunicatingWithServer=Erreur lors de la communication avec le serveur
|
||||
userManagement=Gestion des utilisateurs
|
||||
regattaStructureImport=Importation de la structure de la régate
|
||||
filteredBy=filtré par
|
||||
@@ -1242,6 +1279,7 @@ noFleetsDefined=Aucune flotte définie
|
||||
successfullyCreatedRegattas=Création des régates réussie
|
||||
errorTryingToRegisterRacesForTracking=Erreur lors de la tentative d''enregistrement des courses {0} pour le suivi : {1}. Vérifiez la syntaxe de l''URL stockée/du direct.
|
||||
errorDeterminingPolarAvailability=Erreur lors de la détermination de la disponibilité des données polaires/VPP pour la course {0} : {1}
|
||||
error=Erreur
|
||||
fileStorage=Stockage du fichier
|
||||
active=Actif
|
||||
scoringSchemeHighPointEssOverallDescription=Score en points. Le vainqueur d''un Act totalise 10 points, le 2e - 9 points, etc. En cas d''égalité au classement général des Extreme Sailing Series, la victoire est accordée au concurrent ayant remporté le plus d''Act. Si l''égalité persiste, le résultat obtenu au dernier Act sera utilisé.
|
||||
@@ -1284,6 +1322,7 @@ showCompetitorFullNameColumn=Nom complet du concurrent
|
||||
alwaysShowCompetitorNationalityColumn=Afficher toujours la nationalité du concurrent
|
||||
alwaysShowCompetitorNationalityColumnTooltip=Si disponibles, afficher les deux : le drapeau national ainsi que l''image du concurrent
|
||||
loadingDimensionValues=Chargement des valeurs de dimension
|
||||
runningQuery=Requête en cours
|
||||
inviteBuoyTenders=Inviter navire baliseur
|
||||
orMultipleEmails=ou plusieurs adresses e-mails séparées par des virgules
|
||||
courseOverGroundTrueDegreesTooltip=Route fond vraie en degrés
|
||||
@@ -1291,6 +1330,11 @@ courseOverGroundTrueDegrees=Route fond
|
||||
distanceIncludingGateStartInMeters=Distance (si départ au lièvre)
|
||||
distanceTraveledIncludingGateStartTooltip=La distance naviguée du départ de la portion de parcours jusqu''à sa fin\nou jusqu''à l''heure actuelle (si la portion de parcours n''est pas terminée).\nSi la portion de parcours inclut un départ au lièvre, la distance de la bouée de ligne jusqu''à la position de départ est incluse \npour permettre de comparer les concurrents même si leur départ ne s''est pas fait à la même heure.
|
||||
raceDistanceTraveledIncludingGateStartTooltip=La distance naviguée du départ de la course jusqu''à sa fin\nou jusqu''à l''heure actuelle (si la course n''est pas terminée).\nEn cas de départ au lièvre, la distance de la bouée de ligne jusqu''à la position de départ est incluse \npour permettre de comparer les concurrents même si leur départ ne s''est pas fait à la même heure.
|
||||
results=Résultats
|
||||
groupName=Nom du groupe
|
||||
valueAscending=Valeur (ascendant)
|
||||
valueDescending=Valeur (descendant)
|
||||
sortBy=Trier par
|
||||
dashboardHeader=Tableau de bord
|
||||
dashboardNoWindBotAvailableHeader=Le bot du vent n''est pas disponible.
|
||||
dashboardNoWindBotAvailableMessage=Pour pouvoir recevoir des données de vent depuis des unités de mesure du vent, assurez-vous que le bot du vent est allumé et connecté à SAP Sailing Analytics.
|
||||
@@ -1326,12 +1370,16 @@ dashboardRCBoat=Bateau du comité de course
|
||||
fixedMarkPassing=(fixé)
|
||||
suppressedMarkPassing=(supprimé)
|
||||
windUp=Orienté par rapport au sens du vent (le vent vient du haut de la carte)
|
||||
filterBy=Filtrer par
|
||||
currentFilterSelection=Sélection du filtre actuel
|
||||
notCapableOfGeneratingACodeForIdentifier=Je ne suis pas capable de générer un code pour cet identifiant.
|
||||
serverUrl=URL du serveur
|
||||
rotatedFromTrueNorth=Pivoté de {0} degrés à partir du vrai Nord.
|
||||
clickToToggleWindUp=Touchez/Cliquez pour basculer entre l''affichage orienté nord et l''affichage par rapport au sens du vent
|
||||
clickToToggleWindStreamlets=Touchez/cliquez pour afficher ou masquer les couloirs de vent.
|
||||
startLineToFirstMarkTriangle=Distance entre le départ et la première marque ({0} m)
|
||||
dataMiningComponentsHaveBeenUpdated=Les composants d''exploration de données ont été mis à jour.
|
||||
dataMiningComponentsNeedReloadDialogMessage=Cliquez sur Recharger pour recharger les composants maintenant. Les données actuellement affichées seront ignorées et une requête par défaut sera exécutée.n\Cliquez sur Fermer pour ne rien faire. L''exploration de données ne fonctionnera pas correctement tant que les composants n''auront pas été rechargés.
|
||||
noDataForEvent=Il n''y a pas encore de données pour cette manifestation.
|
||||
countriesCount={0,number} pays
|
||||
countriesCount[one]={0,number} pays
|
||||
@@ -1429,7 +1477,15 @@ noFinishedRaces=Aucune course terminée pour l''instant.
|
||||
racesOverview=Synthèse des courses
|
||||
listFormatLabel=Format de liste
|
||||
competitionFormatLabel=Format de compétition
|
||||
empty=Vide
|
||||
runAQuery=Exécuter une requête
|
||||
latestRegattaStandings=Classement de régate le plus récent
|
||||
plainText=Texte brut
|
||||
columnChart=Diagramme à colonnes
|
||||
columnChartWithErrorBars=Diagramme à colonnes avec barres d''erreur
|
||||
choosePresentation=Sélectionner la présentation
|
||||
cantDisplayDataOfType=Affichage des données du type {0} impossible
|
||||
shownDecimals=Nombre de décimales
|
||||
openFullscreenView=Ouvrir le mode Plein écran
|
||||
closeFullscreenView=Fermer le mode Plein écran
|
||||
videosCount={0,number} vidéos
|
||||
@@ -1439,8 +1495,15 @@ photosCount[one]={0,number} photo
|
||||
eventsHaveTakenPlace={0} manifestations ont eu lieu.
|
||||
eventsHaveTakenPlace[one]=Une manifestation a eu lieu.
|
||||
raceOffice=Bureau de course
|
||||
analyze=Analyser
|
||||
dataMiningSettings=Options de l''exploration de données
|
||||
multiResultsPresenter=Visualiseur de résultats multiples
|
||||
plainResultsPresenter=Visualiseur de résultats bruts
|
||||
resultsChart=Graphique des résultats
|
||||
tabbedResultsPresenter=Visualiseur de résultats avec onglets
|
||||
polarResultsPresenter=Visualiseur de résultats polaires
|
||||
maneuverSpeedDetailsResultsPresenter=Visualiseur des résultats : détails sur la vitesse lors de la manœuvre
|
||||
dataMiningRetrieval=Récupération de données
|
||||
actionWatch=Regarder
|
||||
actionAnalyze=Analyser
|
||||
denoteAllRacesForRaceLogTrackingShorctut=Raccourci pour marquer toutes les courses pour le suivi par journaux de course
|
||||
@@ -1456,8 +1519,24 @@ defaultName=Par défaut
|
||||
exampleTextForName=Votre nom apparaît de la manière suivante :
|
||||
flightsCount={0,number} départs de deux équipages
|
||||
flightsCount[one]={0,number} départ de deux équipages
|
||||
viewQueryDefinition=Afficher la définition de la requête
|
||||
queryDefinitionViewer=Visualiseur de définitions de requête
|
||||
groupAverageAscending=Moyenne du groupe (ascendant)
|
||||
groupAverageDescending=Moyenne du groupe (descendant)
|
||||
groupMedianAscending=Médiane du groupe (ascendant)
|
||||
groupMedianDescending=Médiane du groupe (descendant)
|
||||
resultsFoundForSearch={0,number} résultats trouvés pour "{1}"
|
||||
resultsFoundForSearch[one]={0,number} résultat trouvé pour "{1}"
|
||||
runPredefinedQuery=Exécuter requête prédéfinie
|
||||
selectPredefinedQuery=Sélectionner requête prédéfinie
|
||||
predefinedQueryRunner=Outil d''exécution de requêtes prédéfinies
|
||||
developerOptions=Options développeur
|
||||
copyToClipboard=Copier dans le presse-papiers
|
||||
code=Code
|
||||
useClassGetName=Utilisez Class.getName() pour les noms des types.
|
||||
useClassGetNameTooltip=Plus stable face aux modifications dans la base de code, mais le fichier de script peut uniquement être utilisé dans l''étendue où les classes sont disponibles.
|
||||
useStringLiterals=Utiliser littéraux de chaîne pour les noms de types
|
||||
useStringLiteralsTooltip=Le fichier de script peut être utilisé partout, mais sera corrompu si la base de code change.
|
||||
errorLoadingDataWithTryAgain=Erreur lors du chargement des données. Nouvel essai dans quelques minutes.
|
||||
addGalleryPhoto=Ajouter photo de la galerie
|
||||
addStageImage=Ajouter image d''étape
|
||||
@@ -1477,6 +1556,7 @@ warningForDisabledCompetitors=Les concurrents suivants ne peuvent pas être insc
|
||||
competitorToolTipMessage={0} a déjà été affecté à la flotte {2} dans la course {3} et ne peut donc pas être affecté à la flotte {1} dans la même course.
|
||||
addMarkToRegatta=Ajouter marque à la régate
|
||||
selectALeaderboardGroup=Sélectionner groupe de palmarès…
|
||||
pleaseSelect=Sélectionnez
|
||||
requiresValidRegatta=Pour identifier la course à afficher, cette page nécessite une régate valide, une colonne de course et un nom de flotte.
|
||||
couldNotObtainRace=Impossible de trouver une course ayant le nom {1} pour la flotte {2} pour une régate ayant le nom {0} : {3}
|
||||
errorTryingToCreateEmbeddedMap=Erreur lors de la tentative de création de la carte intégrée : {0}
|
||||
@@ -1756,9 +1836,30 @@ eventRegattaHeaderLegendGpsNo=Aucune donnée de suivi
|
||||
eventRegattaHeaderLegendWindNo=Aucune donnée de vent
|
||||
eventRegattaHeaderLegendVideoNo=Aucun flux vidéo
|
||||
eventRegattaHeaderLegendAudioNo=Aucun flux audio
|
||||
angleInDegree=Angle en degrés
|
||||
angleInRadian=Angle en radians
|
||||
centralAngleInRadian=Angle au centre en radians
|
||||
centralAngleInDegree=Angle au centre en degrés
|
||||
kilometers=Kilomètres
|
||||
meters=Mètres
|
||||
nauticalMiles=Milles nautiques
|
||||
seaMiles=Milles marins
|
||||
geographicalMiles=Milles géographiques
|
||||
days=Jours
|
||||
hours=Heures
|
||||
minutes=Minutes
|
||||
seconds=Secondes
|
||||
milliseconds=Millisecondes
|
||||
floatNumber=Flottant
|
||||
integer=Entier
|
||||
appendResult=Ajouter résultat
|
||||
sampleColor=Échantillon de couleur
|
||||
sharedSettingsLink=Lier aux options
|
||||
leaderboardPage=Page du palmarès
|
||||
makeDefault=Définir par défaut
|
||||
makeDefaultInProgress=En cours...
|
||||
settingsSavedMessage=Vos options actuelles ont correctement été définies comme options par défaut.
|
||||
settingsSaveErrorMessage=Une erreur s''est produite lors de la définition de vos options comme options par défaut.
|
||||
showLiveNow=Afficher "En direct"
|
||||
useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Utilisez "Interférence temporelle de départ" ou bien "Contrôler suivi à partir des heures de départ et d''arrivée", mais pas les deux.
|
||||
unknownLeaderboardType=Type de palmarès {0} inconnu
|
||||
@@ -1770,13 +1871,17 @@ raceRankShort=Place dans la course
|
||||
showRaceRankColumn=Afficher place dans la course
|
||||
estimatedDistance=Distance estimée
|
||||
estimatedTime=Temps estimé
|
||||
nothingUpcoming=Il n''existe actuellement aucune autre course planifiée.
|
||||
nothingUpcoming=Il n''existe aucune autre course dont le départ est proche.
|
||||
noUpcomingRaceDataAvailable=Aucune donnée concernant la prochaine course n''est disponible.
|
||||
reallyRemoveSeries=Voulez-vous vraiment supprimer la série "{0}" ? Note : tous les journaux de la course seront également supprimés de manière permanente pour cette course.
|
||||
settingsId=ID d''options
|
||||
documentSettingsId=ID d''options du document
|
||||
settingsForId=Options pour l''ID "{0}"
|
||||
userProfileSettingsTabDescription=Les options utilisateur sont générées dans des boîtes de dialogues pour options que vous trouverez à de nombreux endroits sur la page. Cette vue montre toutes vos options regroupées pour les mettre techniquement à disposition des utilisateurs de référence. Soyez prudent : les entrées supprimées ne peuvent pas être restaurées.
|
||||
resetToDefault=Réinitialiser sur les valeurs par défaut
|
||||
resetToDefaultInProgress=Réinitialisation en cours...
|
||||
settingsRemoved=Options par défaut restaurées
|
||||
settingsRemovedError=Impossible de restaurer les options par défaut
|
||||
userSettingsFilter=Filtre d''options
|
||||
requiresRegattaRaceAndLeaderboard=Cette page requiert un nom de régate, un nom de course et un nom de palmarès valides.
|
||||
couldNotFindRaceInRegatta=Impossible de trouver une course nommée {0} pour une régate nommée {1}.
|
||||
@@ -1808,6 +1913,7 @@ errorFetchingDimensionData=Erreur lors de l''accès aux valeurs de dimension de
|
||||
errorFetchingStatistics=Erreur lors de l''accès aux statistiques disponibles du serveur : {0}
|
||||
errorFetchingAggregators=Erreur lors de l''accès aux agrégateurs disponibles du serveur : {0}
|
||||
errorLoadingDataRetrieverChainDefinitions=Erreur lors de la récupération des définitions DataRetrieverChainDefinitions disponibles : {0}
|
||||
errorFetchingComponentsChangedTimepoint=Erreur lors de la récupération de l''heure modifiée du composant du serveur : {0}
|
||||
errorRunningQuery=Erreur lors de l''exécution de la requête : {0}
|
||||
errorReadingWindFixes=Erreur lors de la lecture des points vent {0}
|
||||
errorAddingWindFixForRace=Erreur lors de l''ajout d''un point vent pour la course {0} : {1}
|
||||
@@ -1881,6 +1987,11 @@ minimumRideHeightInMetersTooltip=Hauteur de planing minimale requise en mètres
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSeconds=Durée minimum (s) entre deux tronçons en planing adjacents
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSecondsTooltip=Si cette valeur est renseignée et que la durée entre deux tronçons de planing adjacents est inférieure à celle-ci, ces tronçons de planing adjacents seront combinés en un seul.
|
||||
needToProvideValidMinimumRideHeight=Vous devez fournir une valeur de hauteur de planing minimale valide en mètres.
|
||||
dataMiningErrorMargins=Marges d''erreur
|
||||
elements={0} éléments
|
||||
chooseDifferentDimensionTitle=Sélectionnez une dimension différente.
|
||||
chooseDifferentDimensionMessage=Sélectionnez une dimension différente pour regrouper les résultats.
|
||||
pleaseSelectADimension=Sélectionnez une dimension.
|
||||
currentPortDaggerboardRake=Inclinaison de la dérive bâbord
|
||||
currentPortDaggerboardRakeTooltip=Inclinaison actuelle de la dérive bâbord
|
||||
currentStbdDaggerboardRake=Inclinaison de la dérive tribord
|
||||
|
||||
+111
-1
@@ -9,10 +9,12 @@ trackedBefore=追跡イベントの履歴
|
||||
general=一般
|
||||
listRaces=レース一覧
|
||||
listRegattas=レガッタ一覧
|
||||
numberPairResultsPresenter=散布図
|
||||
wind=風
|
||||
maneuverType=マニューバー
|
||||
windPanelLabel=これは風パネルであり、今のところ完全に空となっています。
|
||||
refresh=リフレッシュ
|
||||
remove=削除
|
||||
removeNumber=削除 ({0})
|
||||
windSource=風源
|
||||
dampeningInterval=制動間隔
|
||||
@@ -51,6 +53,7 @@ trackedRaceConnectedToSelectedRaceName=選択されたレース名に結び付
|
||||
linkToColumn=列にリンク
|
||||
unlink=リンク解除
|
||||
leaderboardName=リーダーボード名
|
||||
cancel=取消
|
||||
pleaseEnterAName=名称を入力してください
|
||||
pleaseEnterABoatClass=艇種を入力してください
|
||||
discardRacesFromHowManyStartedRacesOn=レース除外 (スタート済レースから)
|
||||
@@ -62,6 +65,7 @@ startingFromNumberOfRaces=レース数から開始
|
||||
renameLeaderboard=リーダーボード名称変更
|
||||
addColumnToLeaderboard=リーダーボードに列を追加
|
||||
pleaseEnterNameForNewRaceColumn=新規レース列の名称を入力してください
|
||||
ok=OK
|
||||
medalRace=メダルレース
|
||||
renameRace=レース名称変更
|
||||
openSelectedLeaderboard=選択したリーダーボードを開く
|
||||
@@ -85,6 +89,7 @@ sapSailingAnalytics=Sailing Analytics
|
||||
leaderboard=リーダーボード
|
||||
leaderboards=リーダーボード
|
||||
leaderboardSettings=リーダーボード設定
|
||||
settings=設定
|
||||
selectAtLeastOneLegDetail=レグ詳細を少なくとも 1 つ選択
|
||||
currentSpeedOverGroundInKnots=SOG
|
||||
currentSpeedOverGroundInKnotsTooltip=現在の対地速力です。
|
||||
@@ -168,6 +173,7 @@ tacks=タック
|
||||
jibes=ジャイブ
|
||||
penaltyCircles=ペナルティーサークル
|
||||
medalRaceIsNull=メダルレース値は不可
|
||||
configuration=設定
|
||||
maneuverTypes=マニューバー
|
||||
chooseChart=チャートの選択
|
||||
distanceTraveled=移動した距離
|
||||
@@ -185,11 +191,13 @@ secondsPerNauticalMileUnit=s/NM
|
||||
metersUnit=m
|
||||
millimetersUnit=mm
|
||||
degreesUnit=°
|
||||
close=閉じる
|
||||
compareCompetitors=競技者比較
|
||||
description=内容説明
|
||||
sailNumber=セールナンバー
|
||||
country=国
|
||||
no3LetterCodes=IOC 3 文字コードを検索できませんせした。
|
||||
add=追加
|
||||
delete=削除
|
||||
showCharts=チャート表示
|
||||
raceWithThisNameAlreadyExists=その名称のレースはすでに登録されています。
|
||||
@@ -261,6 +269,7 @@ printHint=適用バージョンを印刷
|
||||
blockedApplyButton=登録されている競技者数が対戦表にある競技者数と同じでありません
|
||||
multiplierInfo=複数のフライトを艇変更がより少なく競技が可能となるよう互いに隣り合わせに作成
|
||||
noPairingListAvailable=印刷機能は選択したリーダーボードレースログに対戦表がすでに適用されている場合にのみ利用が可能です。
|
||||
settingsForComponent={0} の設定
|
||||
noEventsFound=イベントが見つかりませんでした
|
||||
noEventSelected=イベントが選択されていません
|
||||
noLeaderboardsFound=リーダーボードが見つかりませんでした
|
||||
@@ -298,6 +307,8 @@ leaderboardGroup=リーダーボードグループ
|
||||
pleaseEnterNonEmptyDescription=空でない説明を入力してください
|
||||
groupWithThisNameAlreadyExists=この名称のリーダーボードグループはすでに登録されています。
|
||||
detailsOfLeaderboardGroup=リーダーボードグループの詳細
|
||||
edit=編集
|
||||
save=保存
|
||||
abort=中止
|
||||
noLeaderboardGroupWithNameFound={0} という名称のリーダーボードグループは見つかりませんでした
|
||||
overview=概要
|
||||
@@ -332,6 +343,7 @@ degreesShort=度
|
||||
untracked=未追跡
|
||||
delayForLiveMode=ライブモードの遅延:
|
||||
notAvailable=利用不可
|
||||
details=詳細
|
||||
noGroupSelected=グループ未選択
|
||||
combinedWindSourceTypeName=複合
|
||||
legMiddleWindSourceTypeName=レグの中間
|
||||
@@ -413,6 +425,7 @@ simulateAsLiveRace=ライブレースとしてシミュレート
|
||||
simulateWithOffset=スタート前のオフセット (分):
|
||||
boatClassDoesNotMatchSelectedRegatta=選択したレースに、選択したレガッタの艇種 ''{0}'' と同じでない艇種が含まれています。レースはロードされません。
|
||||
regattaExistForSelectedBoatClass=選択した艇種に対して少なくとも 1 つのレガッタがあります。このレースに対してレガッタを初期登録しますか。
|
||||
reload=リロード
|
||||
addRegatta=レガッタ追加...
|
||||
importRegattas=レガッタのインポート...
|
||||
exchangeName=エクスチェンジ名
|
||||
@@ -634,6 +647,7 @@ totalNetPointsColumnTooltip=レガッタにおける競技者の総合得点を
|
||||
windData=風データ
|
||||
gpsData=GPS データ
|
||||
status=ステータス
|
||||
noDataFound=データが見つかりませんでした
|
||||
displayName=名称表示
|
||||
histogram=ヒストグラム
|
||||
numberOfDataPoints=データポイント数
|
||||
@@ -881,9 +895,12 @@ legType=レグタイプ
|
||||
sailID=セールナンバー
|
||||
seriesLeaderboard=シリーズリーダーボード
|
||||
regattaLeaderboards=レガッタリーダーボード
|
||||
clearSelection=選択のクリア
|
||||
running=実行中
|
||||
runAsSubstantive=実行
|
||||
done=実行済
|
||||
lastFinished=最終フィニッシュ
|
||||
run=実行
|
||||
times=回
|
||||
dataAmount=データ量
|
||||
averageCleanedServerTime=∅ サーバ時間のクリア
|
||||
@@ -907,8 +924,12 @@ selectSheet=シート選択
|
||||
cleanedServerTime=サーバ時間のクリア
|
||||
overallTime=全体時間
|
||||
cleanedOverallTime=全体時間のクリア
|
||||
dataMiningResult=データマイニング結果
|
||||
groupBy=グループキー
|
||||
statisticToCalculate=統計の計算
|
||||
queryResultsChartSubtitle={0} データエントリを {1} 秒で処理済
|
||||
noQuerySelected=クエリ未選択
|
||||
runAutomatically=自動的に実行
|
||||
windImport_Upload=アップロード
|
||||
windImport_Title=Expedition から風をインポート
|
||||
windImport_BoatId=艇 ID:
|
||||
@@ -938,9 +959,14 @@ raceTimeTooltip=競技者がスタート変針点を通過したときに計測
|
||||
raceTimeDownwindTooltip=このレースでダウンウィンドで移動した合計時間
|
||||
raceTimeReachingTooltip=このレースでリーチングで移動した合計時間
|
||||
raceTimeUpwindTooltip=このレースでアップウィンドで移動した合計時間
|
||||
noStatisticSelectedError=計算する統計が選択されていません
|
||||
noCustomGrouperScriptTextError=分類スクリプトが空です
|
||||
noDimensionToGroupBySelectedError=グループ別にする次元が選択されていません
|
||||
noGrouperSelectedError=分類タイプが選択されていません
|
||||
noDataRetrieverChainDefinitonSelectedError=データリトリーバが選択されていません
|
||||
queryNotValidBecause=クエリが可能でありません。理由:
|
||||
dataMining=データマイニング
|
||||
errorRunningDataMiningQuery=クエリ実行でエラーが発生しました
|
||||
hideToolbar=ツールバー非表示
|
||||
showSeriesLeaderboards=シリーズリーダーボード表示
|
||||
showOverallLeaderboard=全体リーダーボード表示
|
||||
@@ -963,6 +989,7 @@ id=ID
|
||||
allowReload=リロード許可
|
||||
compress=圧縮
|
||||
compressTooltip=エクスポートサーバインスタンスが少なくとも\nコミット 0fbf6071dea125bec4a56dee55d61c99def4a62e で実行中の場合にのみ使用してください。
|
||||
queryRunner=クエリランナー
|
||||
rerunQueryAfterRefresh=リフレッシュ後にクエリを再実行
|
||||
refreshIntervalMustntBeEmpty=リフレッシュ間隔は空であってはなりません
|
||||
selectionTables=選択テーブル
|
||||
@@ -1047,7 +1074,12 @@ TWATooltip=競技者の方向と風の間のアングル
|
||||
TWA=真の風角度
|
||||
showBoatClassChartsLabel=利用可能な艇種の全体図も表示することができます。
|
||||
showDiagram=ダイアグラム表示
|
||||
runAutomaticallyTooltip=統計やグルーピングなどを変更した後にクエリを自動的に実行します。
|
||||
rerunQueryAfterRefreshTooltip=テーブルがリフレッシュされた後にクエリを再実行します。
|
||||
queryDefinitionProvider=クエリ定義プロバイダ
|
||||
statisticProvider=統計プロバイダ
|
||||
calculateThe=計算:
|
||||
groupingProvider=グルーピングプロバイダ
|
||||
releaseNotes=新規およびリリース履歴
|
||||
hasSplitFleetContiguousScoring=連続的に得点するフリートの分割
|
||||
addRaceLogTracker=RaceLog トラッカー追加
|
||||
@@ -1205,6 +1237,7 @@ showAll=全表示
|
||||
raceVisibilityColumn=可視性
|
||||
enterCarryValueFor=競技者 {0} の持ち越し得点を入力
|
||||
advanced=予選通過
|
||||
basedOn=基準
|
||||
retrieveWith=検索キー
|
||||
mappingDetails=マッピング詳細
|
||||
deviceMappingQrCodeExplanation=追跡アプリを使用している場合は、競技者/マークを選択し、開始時刻と終了時刻を設定してから、この QRCode をスキャンすることによってデバイスマッピングも追加することができます。
|
||||
@@ -1215,6 +1248,10 @@ enterImageURL=画像 URL を入力...
|
||||
enterVideoURL=動画 URL を入力...
|
||||
enterSponsorImageURL=スポンサー画像 URL を入力...
|
||||
enterRaceName=レース名を入力...
|
||||
serverError=サーバにアクセスしようとしてエラーが発生しました。ネットワーク接続を確認して再試行してください。
|
||||
remoteProcedureCall=リモートプロシージャコール
|
||||
serverReplies=サーバ応答
|
||||
errorCommunicatingWithServer=サーバとの通信でエラー発生
|
||||
userManagement=ユーザ管理
|
||||
regattaStructureImport=レガッタ構成のインポート
|
||||
filteredBy=フィルタキー
|
||||
@@ -1242,6 +1279,7 @@ noFleetsDefined=フリートが定義されていません。
|
||||
successfullyCreatedRegattas=レガッタが登録されました
|
||||
errorTryingToRegisterRacesForTracking=追跡するレース {0} を登録しようとしてエラーが発生: {1}。ライブ/格納 URI 構文をチェックしてください。
|
||||
errorDeterminingPolarAvailability=レース {0} のポーラー/VPP データの利用可能性の決定でエラー発生: {1}
|
||||
error=エラー
|
||||
fileStorage=ファイルストレージ
|
||||
active=有効
|
||||
scoringSchemeHighPointEssOverallDescription=得点数によるスコアです。アクトの勝者が 10 点、2 位が 9 点などと得点します。Extreme Sailing シリーズ全体で同点となった場合は、より多くのアクトで勝者となった競技者を上位とします。それでも同じ場合には、最終アクトの結果を用います。
|
||||
@@ -1284,6 +1322,7 @@ showCompetitorFullNameColumn=競技者氏名
|
||||
alwaysShowCompetitorNationalityColumn=競技者国籍を常に表示
|
||||
alwaysShowCompetitorNationalityColumnTooltip=国旗と競技者画像 (利用可能な場合) の両方を表示
|
||||
loadingDimensionValues=次元値ロード中
|
||||
runningQuery=クエリ実行中
|
||||
inviteBuoyTenders=ブイ入札の招待
|
||||
orMultipleEmails=または複数の電子メールをカンマで区切り
|
||||
courseOverGroundTrueDegreesTooltip=真の対地方位角度 (度)
|
||||
@@ -1291,6 +1330,11 @@ courseOverGroundTrueDegrees=COG
|
||||
distanceIncludingGateStartInMeters=距離 (ゲートスタートでの)
|
||||
distanceTraveledIncludingGateStartTooltip=レグ始点からレグ終点まで、またはレグをフィニッシュ\nしていない場合は現時点までに移動した距離です。\nレグにゲートスタートが含まれる場合は、異なる時刻にスタートしたときでも\n競技者を比較するためにピンエンドからスタート位置までの距離が含まれます。
|
||||
raceDistanceTraveledIncludingGateStartTooltip=レース開始からレース終了まで、またはレースがフィニッシュ\nしていない場合は現時点までに移動した距離です。ゲートスタートの場合は、異なる時刻にスタートしたときでも\n競技者を比較するためにピンエンドからスタート位置までの距離が含まれます。
|
||||
results=結果
|
||||
groupName=グループ名
|
||||
valueAscending=値 (昇順)
|
||||
valueDescending=値 (降順)
|
||||
sortBy=ソートキー
|
||||
dashboardHeader=ダッシュボード
|
||||
dashboardNoWindBotAvailableHeader=ウィンドボットは利用できません。
|
||||
dashboardNoWindBotAvailableMessage=風計測ユニットからライブ風データを受信するには、ウィンドボットがオンになっていて、SAP Sailing Analytics に接続されていることを確認してください。
|
||||
@@ -1326,12 +1370,16 @@ dashboardRCBoat=RC 艇
|
||||
fixedMarkPassing=(固定)
|
||||
suppressedMarkPassing=(非表示)
|
||||
windUp=ウィンドアップ (マップの最上部から風を表示)
|
||||
filterBy=フィルタキー
|
||||
currentFilterSelection=現在のフィルタ選択
|
||||
notCapableOfGeneratingACodeForIdentifier=この ID のコードを生成することができません。
|
||||
serverUrl=サーバ URL
|
||||
rotatedFromTrueNorth=真北から {0} 度回転しました。
|
||||
clickToToggleWindUp=タップ/クリックして、風上が上のマップと北が上のマップとで表示を切り替えます
|
||||
clickToToggleWindStreamlets=タップ/クリックして風細流を表示または非表示にします
|
||||
startLineToFirstMarkTriangle=スタートから第一マークまで ({0}m)
|
||||
dataMiningComponentsHaveBeenUpdated=データマイニングコンポーネントが更新されました
|
||||
dataMiningComponentsNeedReloadDialogMessage=リロードをクリックして、コンポーネントをリロードします。これにより、現在表示されているデータが破棄され、デフォルトクエリが実行されます。\n何も行わない場合は閉じるをクリックします。データマイニングは、コンポーネントがリロードされるまでは正しく機能しません。
|
||||
noDataForEvent=このイベントにまだデータが何もありません。
|
||||
countriesCount={0,number} カ国
|
||||
countriesCount[one]={0,number} カ国
|
||||
@@ -1429,8 +1477,15 @@ noFinishedRaces=フィニッシュしたレースがまだありません。
|
||||
racesOverview=レース概要
|
||||
listFormatLabel=レース一覧
|
||||
competitionFormatLabel=競技日
|
||||
empty=空
|
||||
runAQuery=クエリを実行
|
||||
latestRegattaStandings=レガッタ最新順位表
|
||||
plainText=プレーンテキスト
|
||||
columnChart=縦棒グラフ
|
||||
columnChartWithErrorBars=縦棒グラフ (エラーバーあり)
|
||||
choosePresentation=プレゼンテーション選択
|
||||
cantDisplayDataOfType={0} タイプのデータは表示できません。
|
||||
shownDecimals=小数点表示
|
||||
openFullscreenView=全画面ビューを開く
|
||||
closeFullscreenView=全画面ビューを閉じる
|
||||
videosCount={0,number} 動画
|
||||
@@ -1440,8 +1495,15 @@ photosCount[one]={0,number} 写真
|
||||
eventsHaveTakenPlace={0} イベントが行われました
|
||||
eventsHaveTakenPlace[one]=1 つのイベントが行われました
|
||||
raceOffice=レース事務所
|
||||
analyze=分析
|
||||
dataMiningSettings=データマイニング設定
|
||||
multiResultsPresenter=複数結果表示
|
||||
plainResultsPresenter=プレーン結果表示ツール
|
||||
resultsChart=結果チャート
|
||||
tabbedResultsPresenter=タブ結果表示ツール
|
||||
polarResultsPresenter=ポーラー結果表示ツール
|
||||
maneuverSpeedDetailsResultsPresenter=マニューバー速度詳細結果表示ツール
|
||||
dataMiningRetrieval=データ取得
|
||||
actionWatch=視聴
|
||||
actionAnalyze=分析
|
||||
denoteAllRacesForRaceLogTrackingShorctut=レースログ追跡の全レース表示へのショートカット
|
||||
@@ -1457,8 +1519,24 @@ defaultName=デフォルト
|
||||
exampleTextForName=名前は次のようになります:
|
||||
flightsCount={0,number} フライト
|
||||
flightsCount[one]={0,number} フライト
|
||||
viewQueryDefinition=クエリ定義の表示
|
||||
queryDefinitionViewer=クエリ定義ビューア
|
||||
groupAverageAscending=グループ平均 (昇順)
|
||||
groupAverageDescending=グループ平均 (降順)
|
||||
groupMedianAscending=グループ中央値 (昇順)
|
||||
groupMedianDescending=グループ中央値 (降順)
|
||||
resultsFoundForSearch={0,number} 結果が ''{1}’ に見つかりました
|
||||
resultsFoundForSearch[one]={0,number} 結果が ''{1}’ に見つかりました
|
||||
runPredefinedQuery=事前定義クエリを実行
|
||||
selectPredefinedQuery=事前定義クエリを選択
|
||||
predefinedQueryRunner=事前定義クエリランナー
|
||||
developerOptions=開発者オプション
|
||||
copyToClipboard=クリップボードにコピー
|
||||
code=コード
|
||||
useClassGetName=タイプ名に class.getName() を使用
|
||||
useClassGetNameTooltip=コードベースでの変更に対してより堅牢ですが、コードスニペットはクラスが利用できる範囲でのみ使用できます。
|
||||
useStringLiterals=タイプ名に文字列リテラルを使用
|
||||
useStringLiteralsTooltip=このコードスニペットはどこでも使用できますが、コードベースが変更される場合は中断します。
|
||||
errorLoadingDataWithTryAgain=データのロードでエラーが発生しました。しばらくしてから再試行してください。
|
||||
addGalleryPhoto=ギャラリーフォト追加
|
||||
addStageImage=ステージ画像追加
|
||||
@@ -1478,6 +1556,7 @@ warningForDisabledCompetitors=次の競技者はこのレースに登録する
|
||||
competitorToolTipMessage={0} はすでにレース {3} のフリート {2} に割り当てられており、そのため同一レース内でフリート {1} に割り当てることはできません
|
||||
addMarkToRegatta=マークをレガッタに追加
|
||||
selectALeaderboardGroup=リーダーボードグループを選択...
|
||||
pleaseSelect=選択:
|
||||
requiresValidRegatta=このページには、表示するレースを識別するために有効なレガッタ、レース列、およびフリート名が必要です。
|
||||
couldNotObtainRace=名称 {0} のレガッタに対してフリート {2} の名称 {1} でレースが取得できませんでした: {3}
|
||||
errorTryingToCreateEmbeddedMap=埋込マップを登録しようとしてエラーが発生: {0}
|
||||
@@ -1757,9 +1836,30 @@ eventRegattaHeaderLegendGpsNo=航跡データなし
|
||||
eventRegattaHeaderLegendWindNo=風向風速データなし
|
||||
eventRegattaHeaderLegendVideoNo=動画ストリームなし
|
||||
eventRegattaHeaderLegendAudioNo=音声ストリームなし
|
||||
angleInDegree=角度 (度)
|
||||
angleInRadian=角度 (ラジアン)
|
||||
centralAngleInRadian=中心角 (度)
|
||||
centralAngleInDegree=中心角 (ラジアン)
|
||||
kilometers=キロメートル
|
||||
meters=メートル
|
||||
nauticalMiles=海里
|
||||
seaMiles=海里
|
||||
geographicalMiles=地理マイル
|
||||
days=日
|
||||
hours=時間
|
||||
minutes=分
|
||||
seconds=秒
|
||||
milliseconds=ミリ秒
|
||||
floatNumber=浮動小数点型
|
||||
integer=整数
|
||||
appendResult=結果を追加
|
||||
sampleColor=色サンプル
|
||||
sharedSettingsLink=設定にリンク
|
||||
leaderboardPage=リーダーボードページ
|
||||
makeDefault=デフォルトを設定
|
||||
makeDefaultInProgress=実行中です...
|
||||
settingsSavedMessage=現在の設定がデフォルトとして設定されました
|
||||
settingsSaveErrorMessage=使用している設定をデフォルトとして設定する際にエラーが発生しました
|
||||
showLiveNow="実況中" を表示
|
||||
useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes="推定スタート時刻" および "スタート/フィニッシュ時刻からのコントロール追跡" は 1 つだけ使用してください
|
||||
unknownLeaderboardType=未知のリーダーボードタイプ {0}
|
||||
@@ -1771,13 +1871,17 @@ raceRankShort=レースランク
|
||||
showRaceRankColumn=レースランクを表示
|
||||
estimatedDistance=推定距離
|
||||
estimatedTime=推定時間
|
||||
nothingUpcoming=現時点で予定されているレースはありません
|
||||
nothingUpcoming=まもなく開始されるレースはありません
|
||||
noUpcomingRaceDataAvailable=予定されているレースのデータはありません
|
||||
reallyRemoveSeries=シリーズ ''{0}'' を削除しますか。注記: 付属しているレース列のレースログもすべて永続的に削除されます。
|
||||
settingsId=設定 ID
|
||||
documentSettingsId=文書設定 ID
|
||||
settingsForId=ID ''{0}'' の設定
|
||||
userProfileSettingsTabDescription=ユーザ設定は、このページの多くの場所にあるダイアログを設定することによって生成されます。このビューには、収集したすべての設定がパワーユーザ向けの技術的な方法で表示されます。削除したエントリは復元できないため、注意して使用してください。
|
||||
resetToDefault=デフォルトに戻す
|
||||
resetToDefaultInProgress=リセット中です...
|
||||
settingsRemoved=デフォルト設定が復元されました
|
||||
settingsRemovedError=デフォルト設定を復元できませんでした
|
||||
userSettingsFilter=設定フィルタ
|
||||
requiresRegattaRaceAndLeaderboard=このページには有効なレガッタ名、レース名、およびリーダーボード名が必要です。
|
||||
couldNotFindRaceInRegatta=名前 {1} のレガッタに対して名前 {0} のレースが取得できませんでした
|
||||
@@ -1809,6 +1913,7 @@ errorFetchingDimensionData={0} の次元値のフェッチでエラーが発生:
|
||||
errorFetchingStatistics=サーバからの利用可能な統計のフェッチでエラーが発生: {0}
|
||||
errorFetchingAggregators=サーバからの利用可能な集計のフェッチでエラーが発生: {0}
|
||||
errorLoadingDataRetrieverChainDefinitions=利用可能な DataRetrieverChainDefinitions の取得でエラーが発生: {0}
|
||||
errorFetchingComponentsChangedTimepoint=サーバからのコンポーネント変更済タイムポイントのフェッチでエラーが発生: {0}
|
||||
errorRunningQuery=クエリの実行でエラーが発生: {0}
|
||||
errorReadingWindFixes=風フィックス {0} の読込でエラーが発生しました
|
||||
errorAddingWindFixForRace=レース {0} に対する風フィックスの追加でエラーが発生: {1}
|
||||
@@ -1882,6 +1987,11 @@ minimumRideHeightInMetersTooltip=艇がフォイリング状態にあるとみ
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSeconds=隣り合ったフォイリングセグメント間の最小時間 (秒)
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSecondsTooltip=空白でなく、隣り合った 2 つのフォイリングセグメント間の時間がこの値より小さい場合、隣り合ったこれらのフォイリングセグメントは 1 つにマージされます。
|
||||
needToProvideValidMinimumRideHeight=浮上高さの有効な値をメートル単位で指定する必要があります。
|
||||
dataMiningErrorMargins=エラーマージン
|
||||
elements={0} 要素
|
||||
chooseDifferentDimensionTitle=異なる次元の選択
|
||||
chooseDifferentDimensionMessage=結果をグルーピングするための異なる次元を選択してください
|
||||
pleaseSelectADimension=次元を選択してください
|
||||
currentPortDaggerboardRake=左舷ダガーボード傾斜角
|
||||
currentPortDaggerboardRakeTooltip=現在の左舷ダガーボード傾斜角
|
||||
currentStbdDaggerboardRake=右舷ダガーボード傾斜角
|
||||
|
||||
+112
-1
@@ -9,10 +9,12 @@ trackedBefore=Histórico de eventos rastreados
|
||||
general=Geral
|
||||
listRaces=Listar corridas
|
||||
listRegattas=Listar regatas
|
||||
numberPairResultsPresenter=Diagrama de dispersão
|
||||
wind=Vento
|
||||
maneuverType=Manobra
|
||||
windPanelLabel=Este é o painel eólico que até o momento está completamente vazio.
|
||||
refresh=Atualizar
|
||||
remove=Remover
|
||||
removeNumber=Remover ({0})
|
||||
windSource=Origem do vento
|
||||
dampeningInterval=Intervalo de atenuação
|
||||
@@ -51,6 +53,7 @@ trackedRaceConnectedToSelectedRaceName=Corrida rastreada conectada ao nome da co
|
||||
linkToColumn=Link a coluna
|
||||
unlink=Eliminar link
|
||||
leaderboardName=Nome do painel de classificação
|
||||
cancel=Cancelar
|
||||
pleaseEnterAName=Insira um nome
|
||||
pleaseEnterABoatClass=Insira uma classe de barcos
|
||||
discardRacesFromHowManyStartedRacesOn=Descartar mais um corrida a partir de quantas corridas iniciadas
|
||||
@@ -62,6 +65,7 @@ startingFromNumberOfRaces=A partir de quantas corridas
|
||||
renameLeaderboard=Renomear painel de classificação
|
||||
addColumnToLeaderboard=Adicionar coluna ao painel de classificação
|
||||
pleaseEnterNameForNewRaceColumn=Insira um nome para a coluna da corrida nova
|
||||
ok=OK
|
||||
medalRace=Corrida para medalha
|
||||
renameRace=Renomear corrida
|
||||
openSelectedLeaderboard=Abrir painel de classificação selecionado
|
||||
@@ -85,6 +89,7 @@ sapSailingAnalytics=Sailing Analytics
|
||||
leaderboard=Painel de classificação
|
||||
leaderboards=Painéis de classificação
|
||||
leaderboardSettings=Configurações do painel de classificação
|
||||
settings=Configurações
|
||||
selectAtLeastOneLegDetail=Selecionar pelo menos um detalhe da perna
|
||||
currentSpeedOverGroundInKnots=SOG
|
||||
currentSpeedOverGroundInKnotsTooltip=A velocidade no fundo atual.
|
||||
@@ -168,6 +173,7 @@ tacks=Cambadas
|
||||
jibes=Jaibes
|
||||
penaltyCircles=Voltas de punição
|
||||
medalRaceIsNull=Valor de corrida para medalha não permitido
|
||||
configuration=Configuração
|
||||
maneuverTypes=Manobras
|
||||
chooseChart=Selecionar diagrama
|
||||
distanceTraveled=Distância navegada
|
||||
@@ -185,11 +191,13 @@ secondsPerNauticalMileUnit=s/NM
|
||||
metersUnit=m
|
||||
millimetersUnit=mm
|
||||
degreesUnit=°
|
||||
close=Encerrar
|
||||
compareCompetitors=Comparar competidores
|
||||
description=Descrição
|
||||
sailNumber=Número da vela
|
||||
country=País
|
||||
no3LetterCodes=Impossível encontrar os códigos de 3 letras do COI.
|
||||
add=Adicionar
|
||||
delete=Eliminar
|
||||
showCharts=Visualizar diagramas
|
||||
raceWithThisNameAlreadyExists=Já existe uma corrida com esse nome.
|
||||
@@ -261,6 +269,7 @@ printHint=Imprime a versão aplicada
|
||||
blockedApplyButton=Os competidores registrados são diferentes dos competidores da lista de pares!
|
||||
multiplierInfo=Multiplica os voos e cria-os uns junto aos outros de modo que seja possível uma competição com menos mudanças de barco.
|
||||
noPairingListAvailable=A função de impressão só está disponível caso já tenha sido aplicada uma lista de pares aos registros de corridas dos painéis de classificação selecionados.
|
||||
settingsForComponent=Configurações para {0}
|
||||
noEventsFound=Nenhum evento encontrado
|
||||
noEventSelected=Nenhum evento selecionado
|
||||
noLeaderboardsFound=Nenhum painel de classificação encontrado
|
||||
@@ -298,6 +307,8 @@ leaderboardGroup=Grupo de painéis de classificação
|
||||
pleaseEnterNonEmptyDescription=Insira uma descrição não vazia
|
||||
groupWithThisNameAlreadyExists=Já existe um grupo de painéis de classificação com este nome.
|
||||
detailsOfLeaderboardGroup=Detalhes do grupo de painéis de classificação
|
||||
edit=Processar
|
||||
save=Gravar
|
||||
abort=Cancelar
|
||||
noLeaderboardGroupWithNameFound=Não foi encontrado um grupo de painéis de classificação com o nome {0}
|
||||
overview=Síntese
|
||||
@@ -332,6 +343,7 @@ degreesShort=graus
|
||||
untracked=Não rastreado
|
||||
delayForLiveMode=Atraso para modo ao vivo:
|
||||
notAvailable=Não disponível
|
||||
details=Detalhes
|
||||
noGroupSelected=Nenhum grupo selecionado
|
||||
combinedWindSourceTypeName=Combinado
|
||||
legMiddleWindSourceTypeName=Meio da perna
|
||||
@@ -413,6 +425,7 @@ simulateAsLiveRace=Simular como corrida ao vivo
|
||||
simulateWithOffset=Deslocamento antes da partida em minutos:
|
||||
boatClassDoesNotMatchSelectedRegatta=As corridas selecionadas contêm classes de barcos que não são as mesmas da classe de barcos ''{0}'' da regata selecionada. Não será carregada nenhuma corrida.
|
||||
regattaExistForSelectedBoatClass=Existe pelo menos uma regata para as classes de barcos selecionadas. Criar regatas padrão para essas corridas?
|
||||
reload=Recarregar
|
||||
addRegatta=Adicionar regata...
|
||||
importRegattas=Importar regatas...
|
||||
exchangeName=Trocar nome
|
||||
@@ -634,6 +647,7 @@ totalNetPointsColumnTooltip=O total de pontos líquidos de um competidor na rega
|
||||
windData=Dados do vento
|
||||
gpsData=Dados do GPS
|
||||
status=Status
|
||||
noDataFound=Não foram encontrados dados
|
||||
displayName=Nome de exibição
|
||||
histogram=Histograma
|
||||
numberOfDataPoints=Número de pontos de dados
|
||||
@@ -881,9 +895,12 @@ legType=Tipo de perna
|
||||
sailID=Número da vela
|
||||
seriesLeaderboard=Painel de classificação da série
|
||||
regattaLeaderboards=Painéis de classificação de regata
|
||||
clearSelection=Anular seleção
|
||||
running=Em competição
|
||||
runAsSubstantive=Competir
|
||||
done=Concluído
|
||||
lastFinished=Último a concluir
|
||||
run=Competir
|
||||
times=vezes
|
||||
dataAmount=Quantidade de dados
|
||||
averageCleanedServerTime=∅ tempo de servidor anulado
|
||||
@@ -907,8 +924,12 @@ selectSheet=Selecionar folha
|
||||
cleanedServerTime=Tempo de servidor anulado
|
||||
overallTime=Tempo geral
|
||||
cleanedOverallTime=Tempo geral anulado
|
||||
dataMiningResult=Resultado de data mining
|
||||
groupBy=Agrupar por
|
||||
statisticToCalculate=Calcular estatística
|
||||
queryResultsChartSubtitle=Percorreu {0} entradas de dados em {1} segundos
|
||||
noQuerySelected=Nenhuma consulta selecionada
|
||||
runAutomatically=Executar automaticamente
|
||||
windImport_Upload=Carregar
|
||||
windImport_Title=Importar vento de Expedition
|
||||
windImport_BoatId=ID do barco:
|
||||
@@ -938,9 +959,14 @@ raceTimeTooltip=Tempo total navegado nesta corrida, começando a contagem quando
|
||||
raceTimeDownwindTooltip=Tempo total navegado a sotavento nesta corrida
|
||||
raceTimeReachingTooltip=Tempo total navegado a través nesta corrida
|
||||
raceTimeUpwindTooltip=Tempo total navegado a barlavento nesta corrida
|
||||
noStatisticSelectedError=Não foi selecionada uma estatística para calcular
|
||||
noCustomGrouperScriptTextError=O script do sistema de agrupamento está vazio
|
||||
noDimensionToGroupBySelectedError=Nenhuma dimensão pela qual efetuar o agrupamento selecionada
|
||||
noGrouperSelectedError=Nenhum tipo de sistema de agrupamento selecionado
|
||||
noDataRetrieverChainDefinitonSelectedError=Nenhum recuperador de dados selecionado
|
||||
queryNotValidBecause=Nenhuma consulta possível, pois
|
||||
dataMining=Data mining
|
||||
errorRunningDataMiningQuery=Ocorreu um erro ao executar a consulta
|
||||
hideToolbar=Ocultar barra de ferramentas
|
||||
showSeriesLeaderboards=Visualizar painéis de classificação da série
|
||||
showOverallLeaderboard=Visualizar painel de classificação geral
|
||||
@@ -963,6 +989,7 @@ id=ID
|
||||
allowReload=Permitir recarregamento
|
||||
compress=Comprimir
|
||||
compressTooltip=Utilizar somente se a instância do servidor de exportação estiver sendo executada pelo menos\ncom o commit 0fbf6071dea125bec4a56dee55d61c99def4a62e.
|
||||
queryRunner=Executor de consulta
|
||||
rerunQueryAfterRefresh=Executar consulta novamente após atualização
|
||||
refreshIntervalMustntBeEmpty=O intervalo de atualização não deve estar em branco
|
||||
selectionTables=Tabelas de seleção
|
||||
@@ -1047,7 +1074,12 @@ TWATooltip=O ângulo entre a direção dos competidores e o vento
|
||||
TWA=Ângulo do vento verdadeiro
|
||||
showBoatClassChartsLabel=Você também pode ver o diagrama geral para as classes de barcos disponíveis.
|
||||
showDiagram=Visualizar diagrama
|
||||
runAutomaticallyTooltip=Execute a consulta automaticamente, após modificar, por exemplo, a estatística ou o agrupamento.
|
||||
rerunQueryAfterRefreshTooltip=Executa novamente a consulta após a atualização das tabelas.
|
||||
queryDefinitionProvider=Fornecedor da definição da consulta
|
||||
statisticProvider=Fornecedor da estatística
|
||||
calculateThe=Calcular
|
||||
groupingProvider=Fornecedor do agrupamento
|
||||
releaseNotes=Novidades e histórico de releases
|
||||
hasSplitFleetContiguousScoring=Flotilhas divididas com pontuação contínua
|
||||
addRaceLogTracker=Adicionar rastreador RaceLog
|
||||
@@ -1205,6 +1237,7 @@ showAll=Visualizar tudo
|
||||
raceVisibilityColumn=Visibilidade
|
||||
enterCarryValueFor=Inserir pontos transferidos para competidor {0}
|
||||
advanced=Avançado
|
||||
basedOn=com base em
|
||||
retrieveWith=Recuperar com
|
||||
mappingDetails=Detalhes de mapeamento
|
||||
deviceMappingQrCodeExplanation=Se você estiver utilizando o app de rastreamento, você também pode adicionar o mapeamento do dispositivo selecionando um competidor/marca, definindo as horas de partida e chegada e digitalizando depois este código QR.
|
||||
@@ -1215,6 +1248,10 @@ enterImageURL=Inserir URL de imagem...
|
||||
enterVideoURL=Inserir URL de vídeo...
|
||||
enterSponsorImageURL=Inserir URL de imagem de patrocinador...
|
||||
enterRaceName=Inserir nome da corrida...
|
||||
serverError=Ocorreu um erro ao tentar contatar o servidor. Verifique sua conexão à rede e tente novamente.
|
||||
remoteProcedureCall=Chamada de procedimento remoto
|
||||
serverReplies=Respostas do servidor
|
||||
errorCommunicatingWithServer=Erro ao comunicar com o servidor
|
||||
userManagement=Administração de usuários
|
||||
regattaStructureImport=Importação de estrutura da regata
|
||||
filteredBy=filtrado por
|
||||
@@ -1242,6 +1279,7 @@ noFleetsDefined=Nenhuma flotilha definida.
|
||||
successfullyCreatedRegattas=Regatas criadas com êxito
|
||||
errorTryingToRegisterRacesForTracking=Erro ao tentar registrar corridas {0} para rastreamento: {1}. Verificar sintaxe de URI ao vivo/armazenado.
|
||||
errorDeterminingPolarAvailability=Erro ao determinar disponibilidade de dados de carta polar/VPP para corrida {0}: {1}
|
||||
error=Erro
|
||||
fileStorage=Armazenamento de arquivos
|
||||
active=Ativo
|
||||
scoringSchemeHighPointEssOverallDescription=Pontuação em pontos. O vencedor de uma etapa pontua 10 pontos, o 2º - 9 pontos, .... O desempate na pontuação geral da Extreme Sailing Series é efetuado a favor do competidor com o maior número de vitórias em etapas. Se isso não efetuar o desempate, será utilizado o resultado na última etapa.
|
||||
@@ -1284,6 +1322,7 @@ showCompetitorFullNameColumn=Nome completo do competidor
|
||||
alwaysShowCompetitorNationalityColumn=Exibir sempre a nacionalidade do competidor
|
||||
alwaysShowCompetitorNationalityColumnTooltip=Exibir ambos, bandeiras de nacionalidade e imagens do competidor, se disponíveis
|
||||
loadingDimensionValues=Carregando valores de dimensão
|
||||
runningQuery=Executando consulta
|
||||
inviteBuoyTenders=Convidar navios-balizadores
|
||||
orMultipleEmails=ou vários e-mails separados por vírgula
|
||||
courseOverGroundTrueDegreesTooltip=Percurso verdadeiro no fundo em graus
|
||||
@@ -1291,6 +1330,11 @@ courseOverGroundTrueDegrees=COG
|
||||
distanceIncludingGateStartInMeters=Distância (com início do portão)
|
||||
distanceTraveledIncludingGateStartTooltip=A distância navegada desde o início até o fim da perna\nou até a data/hora atual, se a perna não estiver concluída.\nSe a perna incluir o início de um portão, a distância desde o fim da marcação até a posição inicial é incluída\npara ser possível comparar os competidores mesmo quando começam em horas diferentes.
|
||||
raceDistanceTraveledIncludingGateStartTooltip=A distância navegada desde o início até o fim da corrida\nou até a data/hora atual, se a corrida não estiver concluída.\nPara o início de um portão, a distância desde o fim da marcação até a posição inicial é incluída\npara ser possível comparar os competidores mesmo quando começam em horas diferentes.
|
||||
results=Resultados
|
||||
groupName=Nome do grupo
|
||||
valueAscending=Valor (crescente)
|
||||
valueDescending=Valor (decrescente)
|
||||
sortBy=Ordenar por
|
||||
dashboardHeader=Painel
|
||||
dashboardNoWindBotAvailableHeader=O Wind Bot não está disponível.
|
||||
dashboardNoWindBotAvailableMessage=Para receber dados do vento em tempo real de unidades de medida do vento, certifique-se de que o Wind Bot está ativado e conectado ao SAP Sailing Analytics.
|
||||
@@ -1326,12 +1370,16 @@ dashboardRCBoat=Barco de rádio-controle
|
||||
fixedMarkPassing=(fixo)
|
||||
suppressedMarkPassing=(suprimido)
|
||||
windUp=Orientação pelo vento (visualizar vento no topo do mapa)
|
||||
filterBy=Filtrar por
|
||||
currentFilterSelection=Seleção de filtro atual
|
||||
notCapableOfGeneratingACodeForIdentifier=Não é possível gerar um código para este identificador.
|
||||
serverUrl=URL de servidor
|
||||
rotatedFromTrueNorth=Efetuou a rotação de {0} graus desde o norte verdadeiro.
|
||||
clickToToggleWindUp=Tocar/clicar para comutar entre exibição do mapa com orientação pelo vento e pelo norte
|
||||
clickToToggleWindStreamlets=Tocar/clicar para visualizar ou ocultar os cursos do vento
|
||||
startLineToFirstMarkTriangle=Partida para primeira marca ({0}m)
|
||||
dataMiningComponentsHaveBeenUpdated=Os componentes de data mining foram atualizados
|
||||
dataMiningComponentsNeedReloadDialogMessage=Clicar em Recarregar para recarregar os componentes agora. Isto irá descartar os dados exibidos atualmente e executar uma consulta padrão.\nClicar em Fechar para não efetuar nada. O data mining não irá funcionar corretamente até ser efetuado o recarregamento dos componentes.
|
||||
noDataForEvent=Ainda não existem dados para o evento.
|
||||
countriesCount={0,number} países
|
||||
countriesCount[one]={0,number} país
|
||||
@@ -1429,7 +1477,15 @@ noFinishedRaces=Ainda não existem corridas concluídas.
|
||||
racesOverview=Síntese de corridas
|
||||
listFormatLabel=Formato de lista
|
||||
competitionFormatLabel=Formato da competição
|
||||
empty=Vazio
|
||||
runAQuery=Executar uma consulta
|
||||
latestRegattaStandings=Posições da última regata
|
||||
plainText=Texto simples
|
||||
columnChart=Diagrama de colunas
|
||||
columnChartWithErrorBars=Diagrama de colunas com barras de erros
|
||||
choosePresentation=Selecionar apresentação
|
||||
cantDisplayDataOfType=Não é possível exibir dados do tipo {0}
|
||||
shownDecimals=Decimais exibidos
|
||||
openFullscreenView=Abrir visão de tela inteira
|
||||
closeFullscreenView=Fechar visão de tela inteira
|
||||
videosCount={0,number} vídeos
|
||||
@@ -1439,8 +1495,15 @@ photosCount[one]={0,number} foto
|
||||
eventsHaveTakenPlace=Foram realizados {0} eventos
|
||||
eventsHaveTakenPlace[one]=Foi realizado um evento
|
||||
raceOffice=Secretaria do evento
|
||||
analyze=Analisar
|
||||
dataMiningSettings=Configurações de data mining
|
||||
multiResultsPresenter=Apresentador de vários resultados
|
||||
plainResultsPresenter=Apresentador de resultados simples
|
||||
resultsChart=Diagrama de resultados
|
||||
tabbedResultsPresenter=Apresentador de resultados por fichas
|
||||
polarResultsPresenter=Apresentador de resultados da carta polar
|
||||
maneuverSpeedDetailsResultsPresenter=Apresentador de resultados detalhados da velocidade da manobra
|
||||
dataMiningRetrieval=Obtenção de dados
|
||||
actionWatch=Ver
|
||||
actionAnalyze=Analisar
|
||||
denoteAllRacesForRaceLogTrackingShorctut=Atalho para denotar todas as corridas para rastreamento do registro de corridas
|
||||
@@ -1456,8 +1519,24 @@ defaultName=Padrão
|
||||
exampleTextForName=Seu nome é parecido com:
|
||||
flightsCount={0,number} voos
|
||||
flightsCount[one]={0,number} voo
|
||||
viewQueryDefinition=Ver definição da consulta
|
||||
queryDefinitionViewer=Visualizador de definição da consulta
|
||||
groupAverageAscending=Média do grupo (crescente)
|
||||
groupAverageDescending=Média do grupo (decrescente)
|
||||
groupMedianAscending=Mediana do grupo (crescente)
|
||||
groupMedianDescending=Mediana do grupo (decrescente)
|
||||
resultsFoundForSearch={0,number} resultados encontrados para ''{1}''
|
||||
resultsFoundForSearch[one]={0,number} resultado encontrado para ''{1}''
|
||||
runPredefinedQuery=Executar consulta predefinida
|
||||
selectPredefinedQuery=Selecionar consulta predefinida
|
||||
predefinedQueryRunner=Executor de consulta predefinida
|
||||
developerOptions=Opções do desenvolvedor
|
||||
copyToClipboard=Copiar para o clipboard
|
||||
code=Código
|
||||
useClassGetName=Utilizar Class.getName() para nomes de tipo
|
||||
useClassGetNameTooltip=Mais robusto em relação às modificações na base do código, mas o trecho do código só pode ser utilizado no âmbito em que as classes estão disponíveis.
|
||||
useStringLiterals=Utilizar literais de cadeia para nomes de tipo
|
||||
useStringLiteralsTooltip=O trecho do código pode ser utilizado em qualquer local, mas será quebrado se a base do código for modificada.
|
||||
errorLoadingDataWithTryAgain=Erro ao carregar dados. Tentar novamente dentro de momentos.
|
||||
addGalleryPhoto=Adicionar foto da galeria
|
||||
addStageImage=Adicionar imagem da etapa
|
||||
@@ -1477,6 +1556,7 @@ warningForDisabledCompetitors=Os competidores seguintes não podem ser registrad
|
||||
competitorToolTipMessage={0} já foi atribuído à flotilha {2} na corrida {3} e por isso não pode ser atribuído à flotilha {1} na mesma corrida
|
||||
addMarkToRegatta=Adicionar marca à regata
|
||||
selectALeaderboardGroup=Selecionar um grupo de painéis de classificação...
|
||||
pleaseSelect=Selecione
|
||||
requiresValidRegatta=Esta página requer uma regata válida, a coluna da corrida e o nome da flotilha para identificar a corrida a ser exibida.
|
||||
couldNotObtainRace=Não foi possível obter uma corrida com o nome {1} para a flotilha {2} para uma regata com o nome {0}: {3}
|
||||
errorTryingToCreateEmbeddedMap=Erro ao tentar criar o mapa integrado: {0}
|
||||
@@ -1756,9 +1836,30 @@ eventRegattaHeaderLegendGpsNo=Sem dados de rastreamento
|
||||
eventRegattaHeaderLegendWindNo=Sem dados de vento
|
||||
eventRegattaHeaderLegendVideoNo=Sem fluxos de vídeo
|
||||
eventRegattaHeaderLegendAudioNo=Sem fluxos de áudio
|
||||
angleInDegree=Ângulo em graus
|
||||
angleInRadian=Ângulo em radianos
|
||||
centralAngleInRadian=Ângulo central em radianos
|
||||
centralAngleInDegree=Ângulo central em graus
|
||||
kilometers=Quilômetros
|
||||
meters=Metros
|
||||
nauticalMiles=Milhas náuticas
|
||||
seaMiles=Milhas marítimas
|
||||
geographicalMiles=Milhas geográficas
|
||||
days=Dias
|
||||
hours=Horas
|
||||
minutes=Minutos
|
||||
seconds=Segundos
|
||||
milliseconds=Milissegundos
|
||||
floatNumber=Margem
|
||||
integer=Número inteiro
|
||||
appendResult=Anexar resultado
|
||||
sampleColor=Amostra de cor
|
||||
sharedSettingsLink=Link com configurações
|
||||
leaderboardPage=Página do painel de classificação
|
||||
makeDefault=Definir como padrão
|
||||
makeDefaultInProgress=Em andamento...
|
||||
settingsSavedMessage=Suas configurações atuais foram definidas com êxito como padrão
|
||||
settingsSaveErrorMessage=Ocorreu um erro ao definir suas configurações como padrão
|
||||
showLiveNow=Exibir "Ao vivo agora"
|
||||
useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Utilizar só um de "Inferência da hora de partida" e "Rastreamento de controle das horas de partida e chegada"
|
||||
unknownLeaderboardType=Tipo de painel de classificação desconhecido {0}
|
||||
@@ -1770,13 +1871,17 @@ raceRankShort=Posição na corrida
|
||||
showRaceRankColumn=Exibir posição na corrida
|
||||
estimatedDistance=Distância estimada
|
||||
estimatedTime=Tempo estimado
|
||||
nothingUpcoming=Atualmente não existem mais corridas planejadas
|
||||
nothingUpcoming=Não existem mais corridas com início em breve
|
||||
noUpcomingRaceDataAvailable=Sem dados da próxima corrida disponíveis
|
||||
reallyRemoveSeries=Você quer realmente remover a série ''{0}''? Nota: todos os registros da corrida para a coluna da corrida anexada também serão removidos definitivamente!
|
||||
settingsId=ID de configurações
|
||||
documentSettingsId=ID de configuração do documento
|
||||
settingsForId=Configurações para ID ''{0}''
|
||||
userProfileSettingsTabDescription=As configurações dos usuários são geradas por diálogos de configurações que podem ser encontrados em vários locais da página. Esta visão exibe todas as suas configurações coletadas de uma forma técnica para usuários avançados. Tenha em atenção que as entradas removidas não podem ser restauradas, por isso utilize-as com cuidado.
|
||||
resetToDefault=Reinicializar para padrão
|
||||
resetToDefaultInProgress=Na reinicialização...
|
||||
settingsRemoved=Configurações padrão restauradas
|
||||
settingsRemovedError=Não foi possível restaurar configurações padrão
|
||||
userSettingsFilter=Filtro de configurações
|
||||
requiresRegattaRaceAndLeaderboard=Esta página necessita de um nome de regata, um nome de corrida e um nome de painel de classificação válidos.
|
||||
couldNotFindRaceInRegatta=Não foi possível obter uma corrida com o nome {0} para uma regata com o nome {1}
|
||||
@@ -1808,6 +1913,7 @@ errorFetchingDimensionData=Erro ao chamar os valores de dimensão de {0}: {1}
|
||||
errorFetchingStatistics=Erro ao chamar as estatísticas disponíveis do servidor: {0}
|
||||
errorFetchingAggregators=Erro ao chamar os agregadores disponíveis do servidor: {0}
|
||||
errorLoadingDataRetrieverChainDefinitions=Erro ao recuperar as definições da cadeia do recuperador de dados disponíveis: {0}
|
||||
errorFetchingComponentsChangedTimepoint=Erro ao chamar data/hora modificada de componentes do servidor: {0}
|
||||
errorRunningQuery=Erro ao executar consulta: {0}
|
||||
errorReadingWindFixes=Erro ao ler pontos fixos de vento {0}
|
||||
errorAddingWindFixForRace=Erro ao adicionar um ponto fixo de vento para corrida {0}: {1}
|
||||
@@ -1881,6 +1987,11 @@ minimumRideHeightInMetersTooltip=A altura mínima de flutuação em metros neces
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSeconds=Duração mínima entre segmentos adjacentes de navegação com hidrofólio (s)
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSecondsTooltip=Se não estiver em branco e o tempo entre dois segmentos adjacentes de navegação com hidrofólio for inferior a este, esses segmentos adjacentes de navegação com hidrofólio serão consolidados em um.
|
||||
needToProvideValidMinimumRideHeight=Você precisa fornecer um valor válido da altura mínima de flutuação em metros.
|
||||
dataMiningErrorMargins=Margens de erro
|
||||
elements={0} elementos
|
||||
chooseDifferentDimensionTitle=Selecionar dimensão diferente
|
||||
chooseDifferentDimensionMessage=Selecionar uma dimensão diferente para os resultados do agrupamento
|
||||
pleaseSelectADimension=Selecione uma dimensão
|
||||
currentPortDaggerboardRake=Inclinação bolina bombordo
|
||||
currentPortDaggerboardRakeTooltip=A inclinação atual da bolina para bombordo
|
||||
currentStbdDaggerboardRake=Inclinação bolina boreste
|
||||
|
||||
+113
-2
@@ -9,10 +9,12 @@ trackedBefore=История отслеживаемых событий
|
||||
general=Общее
|
||||
listRaces=Список гонок
|
||||
listRegattas=Список регат
|
||||
numberPairResultsPresenter=Множество точек
|
||||
wind=Ветер
|
||||
maneuverType=Маневр
|
||||
windPanelLabel=Это панель ветров, которая пока что совсем пуста.
|
||||
refresh=Обновить
|
||||
remove=Удалить
|
||||
removeNumber=Удалить ({0})
|
||||
windSource=Источник ветра
|
||||
dampeningInterval=Интервал смягчения
|
||||
@@ -51,6 +53,7 @@ trackedRaceConnectedToSelectedRaceName=Отслеживаемая гонка с
|
||||
linkToColumn=Связать со столбцом
|
||||
unlink=Отменить связывание
|
||||
leaderboardName=Название таблицы лидеров
|
||||
cancel=Отмена
|
||||
pleaseEnterAName=Введите название
|
||||
pleaseEnterABoatClass=Введите класс лодки
|
||||
discardRacesFromHowManyStartedRacesOn=Исключить еще одну гонку, начиная с числа стартов в гонках
|
||||
@@ -62,6 +65,7 @@ startingFromNumberOfRaces=Начиная с числа гонок
|
||||
renameLeaderboard=Переименовать таблицу лидеров
|
||||
addColumnToLeaderboard=Добавить столбец в таблицу лидеров
|
||||
pleaseEnterNameForNewRaceColumn=Введите название для столбца новой гонки
|
||||
ok=ОК
|
||||
medalRace=Гонка на медали
|
||||
renameRace=Переименовать гонку
|
||||
openSelectedLeaderboard=Открыть выбранную таблицу лидеров
|
||||
@@ -85,7 +89,7 @@ sapSailingAnalytics=Sailing Analytics
|
||||
leaderboard=Таблица лидеров
|
||||
leaderboards=Таблицы лидеров
|
||||
leaderboardSettings=Параметры таблицы лидеров
|
||||
settingsId=Ид. настроек
|
||||
settings=Параметры
|
||||
selectAtLeastOneLegDetail=Выберите подробности минимум одного отрезка
|
||||
currentSpeedOverGroundInKnots=SOG
|
||||
currentSpeedOverGroundInKnotsTooltip=Текущая скорость относительно грунта.
|
||||
@@ -169,6 +173,7 @@ tacks=Поворотов оверштаг
|
||||
jibes=Поворотов фордевинд
|
||||
penaltyCircles=Штрафных кругов
|
||||
medalRaceIsNull=Значение гонки на медали не разрешено
|
||||
configuration=Конфигурация
|
||||
maneuverTypes=Маневры
|
||||
chooseChart=Выберите диаграмму
|
||||
distanceTraveled=Пройденная дистанция
|
||||
@@ -186,11 +191,13 @@ secondsPerNauticalMileUnit=с/NM
|
||||
metersUnit=м
|
||||
millimetersUnit=мм
|
||||
degreesUnit=°
|
||||
close=Закрыть
|
||||
compareCompetitors=Сравнить участников
|
||||
description=Описание
|
||||
sailNumber=Номер на парусе
|
||||
country=Страна
|
||||
no3LetterCodes=Не удалось найти 3-буквенные коды IOC.
|
||||
add=Добавить
|
||||
delete=Удалить
|
||||
showCharts=Показать диаграммы
|
||||
raceWithThisNameAlreadyExists=Гонка с таким названием уже существует.
|
||||
@@ -262,6 +269,7 @@ printHint=Печать примененной версии
|
||||
blockedApplyButton=Число зарегистрированных участников не равно числу участников из списка пар!
|
||||
multiplierInfo=Планируйте флайты таким образом, чтобы обеспечить соревнования с минимально возможной переменой лодок
|
||||
noPairingListAvailable=Функция печати доступна только после применения списка пар к журналам гонок выбранных таблиц лидеров.
|
||||
settingsForComponent={0} — параметры
|
||||
noEventsFound=События не найдены
|
||||
noEventSelected=Не выбрано событие
|
||||
noLeaderboardsFound=Таблицы лидеров не найдены
|
||||
@@ -299,6 +307,8 @@ leaderboardGroup=Группа таблиц лидеров
|
||||
pleaseEnterNonEmptyDescription=Введите непустое описание
|
||||
groupWithThisNameAlreadyExists=Группа таблиц лидеров с таким названием уже существует.
|
||||
detailsOfLeaderboardGroup=Подробности группы таблиц лидеров
|
||||
edit=Изменить
|
||||
save=Сохранить
|
||||
abort=Прервать
|
||||
noLeaderboardGroupWithNameFound=Группа таблиц лидеров с названием {0} не найдена
|
||||
overview=Обзор
|
||||
@@ -333,6 +343,7 @@ degreesShort=град.
|
||||
untracked=Не отслеживается
|
||||
delayForLiveMode=Задержка для оперативного режима:
|
||||
notAvailable=Недоступно
|
||||
details=Подробности
|
||||
noGroupSelected=Не выбрана группа
|
||||
combinedWindSourceTypeName=Объединено
|
||||
legMiddleWindSourceTypeName=Середина отрезка
|
||||
@@ -414,6 +425,7 @@ simulateAsLiveRace=Симулировать как текущую гонку
|
||||
simulateWithOffset=Сдвиг перед стартом в минутах:
|
||||
boatClassDoesNotMatchSelectedRegatta=Выбранные гонки содержат классы лодок, не совпадающие с классом лодок ''{0}'' выбранной регаты. Гонки не будут загружены.
|
||||
regattaExistForSelectedBoatClass=Для выбранных классов лодок имеется минимум одна регата. Создать регаты по умолчанию для соответствующих гонок?
|
||||
reload=Перезагрузить
|
||||
addRegatta=Добавить регату...
|
||||
importRegattas=Импортировать регаты...
|
||||
exchangeName=Имя Exchange
|
||||
@@ -635,6 +647,7 @@ totalNetPointsColumnTooltip=Общая чистая сумма баллов уч
|
||||
windData=Данные о ветре
|
||||
gpsData=Данные GPS
|
||||
status=Статус
|
||||
noDataFound=Данные не найдены
|
||||
displayName=Отображаемое имя
|
||||
histogram=Гистограмма
|
||||
numberOfDataPoints=Число точек данных
|
||||
@@ -882,9 +895,12 @@ legType=Тип отрезка
|
||||
sailID=Номер на парусе
|
||||
seriesLeaderboard=Таблица лидеров серии
|
||||
regattaLeaderboards=Таблицы лидеров регаты
|
||||
clearSelection=Очистить выбор
|
||||
running=Выполнение
|
||||
runAsSubstantive=Выполнить
|
||||
done=Готово
|
||||
lastFinished=Последний финиш
|
||||
run=Выполнить
|
||||
times=раз
|
||||
dataAmount=Объем данных
|
||||
averageCleanedServerTime=∅ Очищенное время сервера
|
||||
@@ -908,8 +924,12 @@ selectSheet=Выбрать лист
|
||||
cleanedServerTime=Очищенное время сервера
|
||||
overallTime=Общее время
|
||||
cleanedOverallTime=Очищенное общее время
|
||||
dataMiningResult=Результат добычи данных
|
||||
groupBy=Группировать по
|
||||
statisticToCalculate=Рассчитать статистику
|
||||
queryResultsChartSubtitle=Обработано {0} зап. данных за {1} с
|
||||
noQuerySelected=Не выбран запрос
|
||||
runAutomatically=Выполнить автоматически
|
||||
windImport_Upload=Отправить
|
||||
windImport_Title=Импортировать ветер из Expedition
|
||||
windImport_BoatId=Ид. лодки:
|
||||
@@ -939,9 +959,14 @@ raceTimeTooltip=Общее время хода в данной гонке, от
|
||||
raceTimeDownwindTooltip=Общее время хода по ветру в данной гонке
|
||||
raceTimeReachingTooltip=Общее время хода полным ветром в данной гонке
|
||||
raceTimeUpwindTooltip=Общее время хода против ветра в данной гонке
|
||||
noStatisticSelectedError=Не выбрана статистика для расчета
|
||||
noCustomGrouperScriptTextError=Скрипт группирования пуст
|
||||
noDimensionToGroupBySelectedError=Не выбрано базовое измерение для группировки
|
||||
noGrouperSelectedError=Не выбран тип группирования
|
||||
noDataRetrieverChainDefinitonSelectedError=Не выбрано средство извлечения данных
|
||||
queryNotValidBecause=Запрос невозможен, так как
|
||||
dataMining=Добыча данных
|
||||
errorRunningDataMiningQuery=При выполнении запроса возникла ошибка
|
||||
hideToolbar=Скрыть панель инструментов
|
||||
showSeriesLeaderboards=Показать таблицы лидеров серии
|
||||
showOverallLeaderboard=Показать итоговую таблицу лидеров
|
||||
@@ -964,6 +989,7 @@ id=Ид.
|
||||
allowReload=Разрешить перезагрузку
|
||||
compress=Сжать
|
||||
compressTooltip=Используйте только при выполнении экспортирующего экземпляра\nсервера с commit 0fbf6071dea125bec4a56dee55d61c99def4a62e.
|
||||
queryRunner=Выполнение запроса
|
||||
rerunQueryAfterRefresh=Повторить запрос после обновления
|
||||
refreshIntervalMustntBeEmpty=Интервал обновления не должен быть пустым
|
||||
selectionTables=Таблица выбора
|
||||
@@ -1048,7 +1074,12 @@ TWATooltip=Угол между направлением участников и
|
||||
TWA=Угол истинного ветра
|
||||
showBoatClassChartsLabel=Также можно просмотреть общую диаграмму для доступных классов лодок.
|
||||
showDiagram=Показать диаграмму
|
||||
runAutomaticallyTooltip=Автоматически выполнять запрос после изменения, например, статистики или группирования.
|
||||
rerunQueryAfterRefreshTooltip=Повторно выполняет запрос после обновления таблиц.
|
||||
queryDefinitionProvider=Поставщик определения запроса
|
||||
statisticProvider=Поставщик статистики
|
||||
calculateThe=Рассчитать
|
||||
groupingProvider=Поставщик группирования
|
||||
releaseNotes=Новости и история выпусков
|
||||
hasSplitFleetContiguousScoring=Разделенные флоты получили сходные оценки
|
||||
addRaceLogTracker=Добавить средство отслеживания журнала гонки
|
||||
@@ -1206,6 +1237,7 @@ showAll=Показать все
|
||||
raceVisibilityColumn=Видимость
|
||||
enterCarryValueFor=Введите перенесенные баллы для участника {0}
|
||||
advanced=Дополнительно
|
||||
basedOn=на базе
|
||||
retrieveWith=Получить с помощью
|
||||
mappingDetails=Подробности сопоставления
|
||||
deviceMappingQrCodeExplanation=Если используется приложение отслеживания, можно добавить также сопоставление устройства, выбрав участника/отметку, установив интервал времени, а затем отсканировав этот QR-код.
|
||||
@@ -1216,6 +1248,10 @@ enterImageURL=Ввести URL-адрес изображения...
|
||||
enterVideoURL=Ввести URL-адрес видео...
|
||||
enterSponsorImageURL=Ввести URL-адрес изображения спонсора...
|
||||
enterRaceName=Ввести название гонки...
|
||||
serverError=При попытке обратиться к серверу возникла ошибка. Проверьте подключение к сети и повторите попытку.
|
||||
remoteProcedureCall=Удаленный вызов процедуры
|
||||
serverReplies=Ответы сервера
|
||||
errorCommunicatingWithServer=Ошибка связи с сервером
|
||||
userManagement=Управление пользователями
|
||||
regattaStructureImport=Импорт структуры регаты
|
||||
filteredBy=отфильтровано по
|
||||
@@ -1243,6 +1279,7 @@ noFleetsDefined=Не определены флоты.
|
||||
successfullyCreatedRegattas=Регаты успешно созданы
|
||||
errorTryingToRegisterRacesForTracking=Ошибка при попытке зарегистрировать гонки {0} для отслеживания: {1}. проверьте синтаксис URI оперативных/хранимых данных.
|
||||
errorDeterminingPolarAvailability=Ошибка при определении доступности полярных/VPP данных для гонки {0}: {1}
|
||||
error=Ошибка
|
||||
fileStorage=Хранилище файлов
|
||||
active=Активно
|
||||
scoringSchemeHighPointEssOverallDescription=Оценка в баллах. Победитель в акте получает 10 баллов, 2-й — 9 баллов, .... Любое равенство в общей оценке Extreme Sailing Series разрешается в пользу участника с наибольшим числом побед в актах. В случае равенства числа побед для разрешения используется последний акт.
|
||||
@@ -1285,6 +1322,7 @@ showCompetitorFullNameColumn=Полное имя участника
|
||||
alwaysShowCompetitorNationalityColumn=Всегда показывать государственную принадлежность участника
|
||||
alwaysShowCompetitorNationalityColumnTooltip=Показывать и флаги государств, и изображения участников (при наличии)
|
||||
loadingDimensionValues=Загрузка значений измерения
|
||||
runningQuery=Выполнение запроса
|
||||
inviteBuoyTenders=Пригласить лоцманов
|
||||
orMultipleEmails=или несколько адресов эл. почты через запятую
|
||||
courseOverGroundTrueDegreesTooltip=Истинный курс относительно грунта в градусах
|
||||
@@ -1292,6 +1330,11 @@ courseOverGroundTrueDegrees=COG
|
||||
distanceIncludingGateStartInMeters=Дистанция (при старте через ворота)
|
||||
distanceTraveledIncludingGateStartTooltip=Дистанция, пройденная от начала отрезка до конца\nили до текущего момента времени, если отрезок не завершен.\nЕсли отрезок включает старт через ворота, дистанция от отметки до стартовой позиции включается,\nчтобы обеспечить сравнение участников даже при старте в разное время.
|
||||
raceDistanceTraveledIncludingGateStartTooltip=Дистанция, пройденная от начала гонки до конца\nили до текущего момента времени, если гонка не завершена.\nДля старта через ворота включается дистанция от привязки до стартовой позиции,\nчтобы обеспечить сравнение участников даже при старте в разное время.
|
||||
results=Результаты
|
||||
groupName=Название группы
|
||||
valueAscending=Значение (по возрастанию)
|
||||
valueDescending=Значение (по убыванию)
|
||||
sortBy=Сортировать по
|
||||
dashboardHeader=Панель
|
||||
dashboardNoWindBotAvailableHeader=WindBot недоступен.
|
||||
dashboardNoWindBotAvailableMessage=Чтобы получать оперативные данные от устройств измерения ветра, убедитесь, что WindBot включен и подключен к SAP Sailing Analytics.
|
||||
@@ -1327,12 +1370,16 @@ dashboardRCBoat=Лодка ГК
|
||||
fixedMarkPassing=(фиксировано)
|
||||
suppressedMarkPassing=(подавляется)
|
||||
windUp=На ветер (показать ветер сверху карты)
|
||||
filterBy=Фильтровать по
|
||||
currentFilterSelection=Текущий выбор фильтра
|
||||
notCapableOfGeneratingACodeForIdentifier=Я не могу сгенерировать код для этого идентификатора.
|
||||
serverUrl=URL-адрес сервера
|
||||
rotatedFromTrueNorth=Повернуто на {0} град. от истинного севера.
|
||||
clickToToggleWindUp=Коснитесь/щелкните для переключения между отображением карты с ветром или севером вверху
|
||||
clickToToggleWindStreamlets=Коснитесь/щелкните для отображения или скрытия потоков ветра
|
||||
startLineToFirstMarkTriangle=От старта до первой отметки ({0} м)
|
||||
dataMiningComponentsHaveBeenUpdated=Компоненты добычи данных обновлены.
|
||||
dataMiningComponentsNeedReloadDialogMessage=Щелкните ''Перезагрузить'', чтобы перезагрузить компоненты сейчас. Текущее отображение данных будет сброшено с выполнением запроса по умолчанию. Добыча данных не будет работать правильно до перезагрузки компонентов.
|
||||
noDataForEvent=Данных для данного события еще нет.
|
||||
countriesCount={0,number} стран
|
||||
countriesCount[one]={0,number} страна
|
||||
@@ -1430,7 +1477,15 @@ noFinishedRaces=Завершенных гонок еще нет
|
||||
racesOverview=Обзор гонок
|
||||
listFormatLabel=Формат списка
|
||||
competitionFormatLabel=Формат соревнования
|
||||
empty=Пусто
|
||||
runAQuery=Выполнить запрос
|
||||
latestRegattaStandings=Позиции в последней регате
|
||||
plainText=Простой текст
|
||||
columnChart=Столбчатая диаграмма
|
||||
columnChartWithErrorBars=Столбчатая диаграмма с планками погрешностей
|
||||
choosePresentation=Выберите представление
|
||||
cantDisplayDataOfType=Невозможно отобразить данные типа {0}
|
||||
shownDecimals=Отображаемые десятичные разряды
|
||||
openFullscreenView=Открыть полноэкранный режим
|
||||
closeFullscreenView=Закрыть полноэкранный режим
|
||||
videosCount={0,number} видео
|
||||
@@ -1440,8 +1495,15 @@ photosCount[one]={0,number} фото
|
||||
eventsHaveTakenPlace=Имело место {0} событий
|
||||
eventsHaveTakenPlace[one]=Имело место одно событие
|
||||
raceOffice=Служба гонки
|
||||
analyze=Анализировать
|
||||
dataMiningSettings=Параметры добычи данных
|
||||
multiResultsPresenter=Презентатор множества результатов
|
||||
plainResultsPresenter=Презентатор простых результатов
|
||||
resultsChart=Диаграмма результатов
|
||||
tabbedResultsPresenter=Презентатор результатов со вкладками
|
||||
polarResultsPresenter=Полярный презентатор результатов
|
||||
maneuverSpeedDetailsResultsPresenter=Демонстратор результатов детализации скорости маневра
|
||||
dataMiningRetrieval=Извлечение данных
|
||||
actionWatch=Смотреть
|
||||
actionAnalyze=Анализировать
|
||||
denoteAllRacesForRaceLogTrackingShorctut=Ярлык для отмены отслеживания журналов всех гонок
|
||||
@@ -1457,8 +1519,24 @@ defaultName=По умолчанию
|
||||
exampleTextForName=Выше имя выглядит так:
|
||||
flightsCount={0,number} полетов
|
||||
flightsCount[one]={0,number} полет
|
||||
viewQueryDefinition=Просмотреть определение запроса
|
||||
queryDefinitionViewer=Средство просмотра определения запроса
|
||||
groupAverageAscending=Среднее группы (по возрастанию)
|
||||
groupAverageDescending=Среднее группы (по убыванию)
|
||||
groupMedianAscending=Медиана группы (по возрастанию)
|
||||
groupMedianDescending=Медиана группы (по убыванию)
|
||||
resultsFoundForSearch=Найдено {0,number} результатов для ''{1}''
|
||||
resultsFoundForSearch[one]=Найден {0,number} результат для ''{1}''
|
||||
runPredefinedQuery=Выполнить готовый запрос
|
||||
selectPredefinedQuery=Выбрать готовый запрос
|
||||
predefinedQueryRunner=Средство выполнения готовых запросов
|
||||
developerOptions=Параметры разработчика
|
||||
copyToClipboard=Копировать в буфер обмена
|
||||
code=Код
|
||||
useClassGetName=Использовать Class.getName() для имен типов
|
||||
useClassGetNameTooltip=Более надежно по сравнению с изменениями в основании кода, но фрагмент кода может быть использован только в области с доступными классами.
|
||||
useStringLiterals=Использовать строковые литералы для имен типов
|
||||
useStringLiteralsTooltip=Фрагмент кода может использоваться где угодно, но будет нарушен в случае изменения основания кода.
|
||||
errorLoadingDataWithTryAgain=Ошибка при загрузке данных. Повтор попытки через несколько секунд.
|
||||
addGalleryPhoto=Добавить фото галереи
|
||||
addStageImage=Добавить изображение этапа
|
||||
@@ -1478,6 +1556,7 @@ warningForDisabledCompetitors=Регистрация следующих учас
|
||||
competitorToolTipMessage={0} уже присвоен флоту {2} в гонке {3} и поэтому не может быть присвоен флоту {1} в той же самой гонке
|
||||
addMarkToRegatta=Добавить отметку к регате
|
||||
selectALeaderboardGroup=Выбрать группу таблиц лидеров...
|
||||
pleaseSelect=Выберите
|
||||
requiresValidRegatta=Эта страница определяет гонку для отображения по допустимым значениям регаты, столбца гонки и названия флота.
|
||||
couldNotObtainRace=Не удалось получить гонку с названием {1} для флота {2} для регаты с названием {0}: {3}
|
||||
errorTryingToCreateEmbeddedMap=Ошибка при попытке создать внедренную карту: {0}
|
||||
@@ -1757,9 +1836,30 @@ eventRegattaHeaderLegendGpsNo=Нет данных отслеживания
|
||||
eventRegattaHeaderLegendWindNo=Нет данных о ветре
|
||||
eventRegattaHeaderLegendVideoNo=Нет видеопотоков
|
||||
eventRegattaHeaderLegendAudioNo=Нет аудиопотоков
|
||||
angleInDegree=Угол в градусах
|
||||
angleInRadian=Угол в радианах
|
||||
centralAngleInRadian=Центральный угол в градусах
|
||||
centralAngleInDegree=Центральный угол в радианах
|
||||
kilometers=Километры
|
||||
meters=Метры
|
||||
nauticalMiles=Морские мили
|
||||
seaMiles=Морские мили
|
||||
geographicalMiles=Географические мили
|
||||
days=Дни
|
||||
hours=Часы
|
||||
minutes=Минуты
|
||||
seconds=Секунды
|
||||
milliseconds=Миллисекунды
|
||||
floatNumber=Плавающее
|
||||
integer=Целое
|
||||
appendResult=Добавить результат
|
||||
sampleColor=Образец цвета
|
||||
sharedSettingsLink=Связать с настройками
|
||||
leaderboardPage=Страница таблицы лидеров
|
||||
makeDefault=Использовать по умолчанию
|
||||
makeDefaultInProgress=Выполняется...
|
||||
settingsSavedMessage=Текущие настройки успешно заданы для использования по умолчанию
|
||||
settingsSaveErrorMessage=При задании настроек для использования по умолчанию возникла ошибка
|
||||
showLiveNow=Показать "Оперативные данные"
|
||||
useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Использовать только один из параметров "Вывод о времени старта" и "Контролировать отслеживание от времени старта и финиша"
|
||||
unknownLeaderboardType=Неизвестный тип таблицы лидеров {0}
|
||||
@@ -1771,12 +1871,17 @@ raceRankShort=Ранг гонки
|
||||
showRaceRankColumn=Показать ранг гонки
|
||||
estimatedDistance=Оценка расстояния
|
||||
estimatedTime=Оценка времени
|
||||
nothingUpcoming=Дальнейших запланированных гонок сейчас нет
|
||||
nothingUpcoming=Нет других гонок, стартующих скоро
|
||||
noUpcomingRaceDataAvailable=Данные предстоящей гонки недоступны
|
||||
reallyRemoveSeries=Действительно удалить серии ''{0}''? Примечание: все журналы для вложенных столбцов гонки также будут окончательно удалены!
|
||||
settingsId=Ид. настроек
|
||||
documentSettingsId=Ид. настроек документа
|
||||
settingsForId=Настройки для ид. ''{0}''
|
||||
userProfileSettingsTabDescription=Пользовательские настройки генерируются диалогами настроек, расположенными во многих местах страницы. Здесь отображено техническое представление всех собранных настроек для ключевых пользователей. Соблюдайте осторожность, так как восстановить удаленные записи невозможно.
|
||||
resetToDefault=Восстановить настройки по умолчанию
|
||||
resetToDefaultInProgress=Выполняется сброс...
|
||||
settingsRemoved=Восстановлены настройки по умолчанию
|
||||
settingsRemovedError=Не удалось восстановить настройки по умолчанию
|
||||
userSettingsFilter=Фильтр настроек
|
||||
requiresRegattaRaceAndLeaderboard=Для этой страницы требуются действительные названия регаты, гонки и таблицы лидеров.
|
||||
couldNotFindRaceInRegatta=Не удалось получить гонку с названием {0} для регаты с названием {1}
|
||||
@@ -1808,6 +1913,7 @@ errorFetchingDimensionData=Ошибка при вызове значений и
|
||||
errorFetchingStatistics=Ошибка при вызове доступной статистики с сервера: {0}
|
||||
errorFetchingAggregators=Ошибка при вызове доступных агрегаторов с сервера: {0}
|
||||
errorLoadingDataRetrieverChainDefinitions=Ошибка при вызове доступных определений цепочек извлечения данных: {0}
|
||||
errorFetchingComponentsChangedTimepoint=Ошибка при вызове отметки времени изменения компонентов с сервера: {0}
|
||||
errorRunningQuery=Ошибка при выполнении запроса: {0}
|
||||
errorReadingWindFixes=Ошибка при считывании замеров ветра {0}
|
||||
errorAddingWindFixForRace=Ошибка при добавлении замера ветра для гонки {0}: {1}
|
||||
@@ -1881,6 +1987,11 @@ minimumRideHeightInMetersTooltip=Минимальная высота просв
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSeconds=Минимальная продолжительность между двумя сегментами в крыльевом режиме (сек)
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSecondsTooltip=Если поле не является пустым, и время между двумя смежными сегментами в крыльевом режиме не превышает указанное значение, смежные сегменты в крыльевом режиме считаются одним сегментом.
|
||||
needToProvideValidMinimumRideHeight=Укажите действительное значение минимальной высоты просвета в метрах.
|
||||
dataMiningErrorMargins=Пределы погрешности
|
||||
elements={0} элем.
|
||||
chooseDifferentDimensionTitle=Выберите другое измерение
|
||||
chooseDifferentDimensionMessage=Выберите другое измерение для группирования результатов
|
||||
pleaseSelectADimension=Выберите измерение
|
||||
currentPortDaggerboardRake=Скос киля на левый борт
|
||||
currentPortDaggerboardRakeTooltip=Текущий скос выдвижного киля на левый борт
|
||||
currentStbdDaggerboardRake=Скос киля на правый борт
|
||||
|
||||
+112
-1
@@ -9,10 +9,12 @@ trackedBefore=已跟踪活动的历史记录
|
||||
general=常规
|
||||
listRaces=比赛轮次清单
|
||||
listRegattas=比赛清单
|
||||
numberPairResultsPresenter=散点图
|
||||
wind=风力
|
||||
maneuverType=操作
|
||||
windPanelLabel=这是风力面板,目前完全空白。
|
||||
refresh=刷新
|
||||
remove=移除
|
||||
removeNumber=移除 ({0})
|
||||
windSource=风源
|
||||
dampeningInterval=阻尼间隔
|
||||
@@ -51,6 +53,7 @@ trackedRaceConnectedToSelectedRaceName=跟踪的比赛轮次已连接到所选
|
||||
linkToColumn=链接到列
|
||||
unlink=取消链接
|
||||
leaderboardName=积分榜名称
|
||||
cancel=取消
|
||||
pleaseEnterAName=请输入名称
|
||||
pleaseEnterABoatClass=请输入船只级别
|
||||
discardRacesFromHowManyStartedRacesOn=从已开始的比赛轮次数开始再放弃一个比赛轮次
|
||||
@@ -62,6 +65,7 @@ startingFromNumberOfRaces=从比赛轮次数开始
|
||||
renameLeaderboard=重命名积分榜
|
||||
addColumnToLeaderboard=向积分榜添加列
|
||||
pleaseEnterNameForNewRaceColumn=请输入新比赛轮次列的名称
|
||||
ok=确定
|
||||
medalRace=奖牌轮
|
||||
renameRace=重命名比赛轮次
|
||||
openSelectedLeaderboard=打开选择的积分榜
|
||||
@@ -85,6 +89,7 @@ sapSailingAnalytics=Sailing Analytics
|
||||
leaderboard=积分榜
|
||||
leaderboards=积分榜
|
||||
leaderboardSettings=积分榜设置
|
||||
settings=设置
|
||||
selectAtLeastOneLegDetail=至少选择一个航段详情
|
||||
currentSpeedOverGroundInKnots=SOG
|
||||
currentSpeedOverGroundInKnotsTooltip=当前实际速度。
|
||||
@@ -168,6 +173,7 @@ tacks=迎风转向
|
||||
jibes=顺风转向
|
||||
penaltyCircles=惩罚转圈
|
||||
medalRaceIsNull=不允许奖牌轮值
|
||||
configuration=配置
|
||||
maneuverTypes=操作
|
||||
chooseChart=选择记录
|
||||
distanceTraveled=航行距离
|
||||
@@ -185,11 +191,13 @@ secondsPerNauticalMileUnit=s/NM
|
||||
metersUnit=m
|
||||
millimetersUnit=mm
|
||||
degreesUnit=°
|
||||
close=关闭
|
||||
compareCompetitors=比较参赛队
|
||||
description=描述
|
||||
sailNumber=帆号
|
||||
country=国家/地区
|
||||
no3LetterCodes=无法找到 IOC 3 个字母的代码。
|
||||
add=添加
|
||||
delete=删除
|
||||
showCharts=显示记录
|
||||
raceWithThisNameAlreadyExists=具有此名称的比赛轮次已存在。
|
||||
@@ -261,6 +269,7 @@ printHint=打印应用的版本
|
||||
blockedApplyButton=注册的参赛队不等于配对清单中的参赛队!
|
||||
multiplierInfo=多个航程,彼此相邻,这样就可以减少船只更换情况进行比赛
|
||||
noPairingListAvailable=打印功能仅在配对清单可应用于选择的积分榜比赛轮次日志时可用。
|
||||
settingsForComponent={0}设置
|
||||
noEventsFound=未找到活动
|
||||
noEventSelected=未选择活动
|
||||
noLeaderboardsFound=未找到积分榜
|
||||
@@ -298,6 +307,8 @@ leaderboardGroup=积分榜组
|
||||
pleaseEnterNonEmptyDescription=请输入非空描述
|
||||
groupWithThisNameAlreadyExists=具有此名称的积分榜组已存在。
|
||||
detailsOfLeaderboardGroup=积分榜组详情
|
||||
edit=编辑
|
||||
save=保存
|
||||
abort=中止
|
||||
noLeaderboardGroupWithNameFound=未找到名称为{0}的积分榜组
|
||||
overview=总览
|
||||
@@ -332,6 +343,7 @@ degreesShort=deg
|
||||
untracked=取消跟踪
|
||||
delayForLiveMode=实况模式延迟:
|
||||
notAvailable=不可用
|
||||
details=详情
|
||||
noGroupSelected=未选择分组
|
||||
combinedWindSourceTypeName=组合
|
||||
legMiddleWindSourceTypeName=航段中部
|
||||
@@ -413,6 +425,7 @@ simulateAsLiveRace=模拟实况比赛轮次
|
||||
simulateWithOffset=起航前的偏移(分钟):
|
||||
boatClassDoesNotMatchSelectedRegatta=所选的比赛轮次包含不同于所选比赛船只级别 "{0}" 的船只级别。将不加载比赛轮次。
|
||||
regattaExistForSelectedBoatClass=所选船只级别至少有一场比赛。是否确定为这些比赛轮次创建默认比赛?
|
||||
reload=重新加载
|
||||
addRegatta=添加比赛...
|
||||
importRegattas=导入比赛...
|
||||
exchangeName=交换机名称
|
||||
@@ -634,6 +647,7 @@ totalNetPointsColumnTooltip=参赛队在比赛中的总净分。\n按名次(
|
||||
windData=风力数据
|
||||
gpsData=GPS 数据
|
||||
status=状态
|
||||
noDataFound=未找到数据
|
||||
displayName=显示名称
|
||||
histogram=直方图
|
||||
numberOfDataPoints=数据点数
|
||||
@@ -881,9 +895,12 @@ legType=航段形式
|
||||
sailID=帆号
|
||||
seriesLeaderboard=系列积分榜
|
||||
regattaLeaderboards=比赛积分榜
|
||||
clearSelection=清除选择
|
||||
running=运行
|
||||
runAsSubstantive=运行
|
||||
done=完成
|
||||
lastFinished=最后完成
|
||||
run=运行
|
||||
times=次数
|
||||
dataAmount=数据量
|
||||
averageCleanedServerTime=∅ 清理服务器时间
|
||||
@@ -907,8 +924,12 @@ selectSheet=选择工作表
|
||||
cleanedServerTime=清理服务器时间
|
||||
overallTime=总时间
|
||||
cleanedOverallTime=清理总时间
|
||||
dataMiningResult=数据挖掘结果
|
||||
groupBy=分组方式
|
||||
statisticToCalculate=计算统计
|
||||
queryResultsChartSubtitle={1}秒内处理{0}个数据条目
|
||||
noQuerySelected=没有查询选择
|
||||
runAutomatically=自动运行
|
||||
windImport_Upload=上传
|
||||
windImport_Title=从导航图导入风力
|
||||
windImport_BoatId=船只编号:
|
||||
@@ -938,9 +959,14 @@ raceTimeTooltip=参赛队在本比赛轮次中越过开始航路点\n(不是
|
||||
raceTimeDownwindTooltip=本轮次比赛顺风航行的总时间
|
||||
raceTimeReachingTooltip=本轮次比赛横风航行的总时间
|
||||
raceTimeUpwindTooltip=本轮次比赛迎风航行的总时间
|
||||
noStatisticSelectedError=未选择待计算的统计
|
||||
noCustomGrouperScriptTextError=群集器脚本为空
|
||||
noDimensionToGroupBySelectedError=未选择分组方式尺寸
|
||||
noGrouperSelectedError=未选择群集器类型
|
||||
noDataRetrieverChainDefinitonSelectedError=未选择数据检索器
|
||||
queryNotValidBecause=无法查询,原因:
|
||||
dataMining=数据挖掘
|
||||
errorRunningDataMiningQuery=运行查询期间出错
|
||||
hideToolbar=隐藏工具栏
|
||||
showSeriesLeaderboards=显示系列积分榜
|
||||
showOverallLeaderboard=显示总积分榜
|
||||
@@ -963,6 +989,7 @@ id=编号
|
||||
allowReload=允许重新加载
|
||||
compress=压缩
|
||||
compressTooltip=仅在导出服务器实例至少通过\n任务 0fbf6071dea125bec4a56dee55d61c99def4a62e 运行时使用。
|
||||
queryRunner=查询执行器
|
||||
rerunQueryAfterRefresh=在刷新后重新运行查询
|
||||
refreshIntervalMustntBeEmpty=刷新间隔不得为空
|
||||
selectionTables=选择表
|
||||
@@ -1047,7 +1074,12 @@ TWATooltip=赛队航行的方向和风的夹角
|
||||
TWA=实际风向角
|
||||
showBoatClassChartsLabel=还可以查看可用船只级别的总直直方图。
|
||||
showDiagram=显示直方图
|
||||
runAutomaticallyTooltip=在更改统计或分组后,自动运行查询。
|
||||
rerunQueryAfterRefreshTooltip=在刷新表后,重新运行查询。
|
||||
queryDefinitionProvider=查询定义提供方
|
||||
statisticProvider=统计提供方
|
||||
calculateThe=计算
|
||||
groupingProvider=分组提供方
|
||||
releaseNotes=消息和版本历史
|
||||
hasSplitFleetContiguousScoring=区分连续得分的船队
|
||||
addRaceLogTracker=添加比赛轮次日志跟踪器
|
||||
@@ -1205,6 +1237,7 @@ showAll=显示全部
|
||||
raceVisibilityColumn=可见性
|
||||
enterCarryValueFor=输入参赛队{0}的得分
|
||||
advanced=高级
|
||||
basedOn=基于
|
||||
retrieveWith=检索依据
|
||||
mappingDetails=映射详情
|
||||
deviceMappingQrCodeExplanation=如果使用跟踪应用,可以通过选择参赛队/标志、设置开始和结束时间,然后扫描此二维码添加设备映射。
|
||||
@@ -1215,6 +1248,10 @@ enterImageURL=输入图像 URL...
|
||||
enterVideoURL=输入视频 URL...
|
||||
enterSponsorImageURL=输入赞助商图像 URL...
|
||||
enterRaceName=输入比赛轮次名称...
|
||||
serverError=尝试联系服务器时出错。请检查网络连接,并重试。
|
||||
remoteProcedureCall=远程过程调用
|
||||
serverReplies=服务器应答
|
||||
errorCommunicatingWithServer=与服务器通信时发生错误
|
||||
userManagement=用户管理
|
||||
regattaStructureImport=比赛结构导入
|
||||
filteredBy=筛选方式
|
||||
@@ -1242,6 +1279,7 @@ noFleetsDefined=未定义船队。
|
||||
successfullyCreatedRegattas=已成功创建比赛
|
||||
errorTryingToRegisterRacesForTracking=尝试注册比赛轮次{0}用于跟踪出错: {1}。检查实况/存储的 URI 语法。
|
||||
errorDeterminingPolarAvailability=确定比赛轮次{0}的极坐标/VPP 数据的可用性出错: {1}
|
||||
error=错误
|
||||
fileStorage=文件存储
|
||||
active=已激活
|
||||
scoringSchemeHighPointEssOverallDescription=得分。 分站赛获胜者得 10 分、第 2 名 9 分、.... 在总体极限帆船系列赛中如有平局,以获得最多分站赛名次的参赛队取得胜利。 如果仍有平局,就以最后一个分站赛的名次打破平局。
|
||||
@@ -1284,6 +1322,7 @@ showCompetitorFullNameColumn=参赛队全名
|
||||
alwaysShowCompetitorNationalityColumn=始终显示参赛队国籍
|
||||
alwaysShowCompetitorNationalityColumnTooltip=如果可用,显示两者:国籍旗帜和参赛队图像
|
||||
loadingDimensionValues=正在加载尺寸值
|
||||
runningQuery=运行查询
|
||||
inviteBuoyTenders=邀请浮标供应船
|
||||
orMultipleEmails=或使用逗号隔开的多个电子邮件
|
||||
courseOverGroundTrueDegreesTooltip=实在对地航向角度
|
||||
@@ -1291,6 +1330,11 @@ courseOverGroundTrueDegrees=对地航向
|
||||
distanceIncludingGateStartInMeters=距离(起航门标)
|
||||
distanceTraveledIncludingGateStartTooltip=如果航段没有结束,从航段起点到终点\n或当前时间点航行的距离。\n如果航段包括起航门标,则包括尾销到起航位置的距离,\n这样,即便在不同时间起航,也可以比较参赛队。
|
||||
raceDistanceTraveledIncludingGateStartTooltip=如果比赛轮次没有结束,从比赛轮次开始到结束\n或当前时间点航行的距离。对于起航门标,包括尾销到起航位置的距离,\n这样,即便在不同时间起航,也可以比较参赛队。
|
||||
results=结果
|
||||
groupName=分组名称
|
||||
valueAscending=值(递增)
|
||||
valueDescending=值(递减)
|
||||
sortBy=排序方式
|
||||
dashboardHeader=仪表盘
|
||||
dashboardNoWindBotAvailableHeader=风力机器人程序不可用。
|
||||
dashboardNoWindBotAvailableMessage=要从风力测量装置接收实况风力数据,请确保开启风力机器人程序,并与 SAP Sailing Analytics 相连。
|
||||
@@ -1326,12 +1370,16 @@ dashboardRCBoat=RC 船只
|
||||
fixedMarkPassing=(固定)
|
||||
suppressedMarkPassing=(禁止)
|
||||
windUp=风向向上(从地图的顶部显示风力)
|
||||
filterBy=筛选方式
|
||||
currentFilterSelection=当前筛选器选择
|
||||
notCapableOfGeneratingACodeForIdentifier=无法为此标识符生成代码。
|
||||
serverUrl=服务器 URL
|
||||
rotatedFromTrueNorth=自真北方向旋转{0}度。
|
||||
clickToToggleWindUp=点按/点击在风向向上和北向上地图显示之间切换
|
||||
clickToToggleWindStreamlets=点按/点击显示或隐藏风流
|
||||
startLineToFirstMarkTriangle=开始经过第一个标志 ({0}m)
|
||||
dataMiningComponentsHaveBeenUpdated=数据挖掘组件已更新
|
||||
dataMiningComponentsNeedReloadDialogMessage=点击“重新加载”,立即重新加载组件。这将放弃当前显示的数据,并运行默认查询。\n点击“关闭”不执行任何操作。在重新加载组件前,数据挖掘不能正常工作。
|
||||
noDataForEvent=活动暂无任何数据。
|
||||
countriesCount={0,number} 个国家/地区
|
||||
countriesCount[one]={0,number} 个国家/地区
|
||||
@@ -1429,7 +1477,15 @@ noFinishedRaces=没有结束的比赛轮次
|
||||
racesOverview=比赛轮次总览
|
||||
listFormatLabel=清单格式
|
||||
competitionFormatLabel=赛制
|
||||
empty=空
|
||||
runAQuery=运行查询
|
||||
latestRegattaStandings=最新比赛排名
|
||||
plainText=纯文本
|
||||
columnChart=柱状图
|
||||
columnChartWithErrorBars=含误差线的柱状图
|
||||
choosePresentation=选择介绍
|
||||
cantDisplayDataOfType=无法显示类型为{0}的数据
|
||||
shownDecimals=显示小数
|
||||
openFullscreenView=打开全屏视图
|
||||
closeFullscreenView=关闭全屏视图
|
||||
videosCount={0,number} 个视频
|
||||
@@ -1439,8 +1495,15 @@ photosCount[one]={0,number} 张照片
|
||||
eventsHaveTakenPlace={0}个活动已举行
|
||||
eventsHaveTakenPlace[one]=已举行一场活动
|
||||
raceOffice=竞赛办公室
|
||||
analyze=分析
|
||||
dataMiningSettings=数据挖掘设置
|
||||
multiResultsPresenter=多结果展示区
|
||||
plainResultsPresenter=纯结果展示区
|
||||
resultsChart=结果记录
|
||||
tabbedResultsPresenter=选项卡式结果展示区
|
||||
polarResultsPresenter=极坐标结果展示区
|
||||
maneuverSpeedDetailsResultsPresenter=操作速度详细结果展示区
|
||||
dataMiningRetrieval=数据检索
|
||||
actionWatch=观看
|
||||
actionAnalyze=分析
|
||||
denoteAllRacesForRaceLogTrackingShorctut=为比赛轮次日志跟踪描述所有比赛轮次的快捷方式
|
||||
@@ -1456,8 +1519,24 @@ defaultName=默认值
|
||||
exampleTextForName=名称如下所示:
|
||||
flightsCount={0,number} 个航程
|
||||
flightsCount[one]={0,number} 个航程
|
||||
viewQueryDefinition=查看查询定义
|
||||
queryDefinitionViewer=查询定义查看器
|
||||
groupAverageAscending=分组平均值(递增)
|
||||
groupAverageDescending=分组平均值(递减)
|
||||
groupMedianAscending=分组中值(递增)
|
||||
groupMedianDescending=分组中值(递减)
|
||||
resultsFoundForSearch=找到 "{1}" 的 {0,number} 个结果
|
||||
resultsFoundForSearch[one]=找到 "{1}" 的 {0,number} 个结果
|
||||
runPredefinedQuery=运行预定义的查询
|
||||
selectPredefinedQuery=选择预定义的查询
|
||||
predefinedQueryRunner=预定义的查询执行器
|
||||
developerOptions=开发人员选项
|
||||
copyToClipboard=复制到剪贴板
|
||||
code=代码
|
||||
useClassGetName=将 Class.getName() 用于类型名称
|
||||
useClassGetNameTooltip=更灵活应对代码库的更改,但是代码片段只能在级别可用的范围内使用。
|
||||
useStringLiterals=将字符串文本用于类型名称
|
||||
useStringLiteralsTooltip=代码片段可在任意位置使用,当如果基本代码更改,其将中断。
|
||||
errorLoadingDataWithTryAgain=加载数据出错。请稍后重试。
|
||||
addGalleryPhoto=添加图库照片
|
||||
addStageImage=添加阶段图像
|
||||
@@ -1477,6 +1556,7 @@ warningForDisabledCompetitors=以下参赛队无法注册此比赛轮次:{0}
|
||||
competitorToolTipMessage={0}已分配到比赛轮次{3}中的船队{2},因此,无法分配到同一比赛轮次中的船队{1}
|
||||
addMarkToRegatta=向比赛添加标志
|
||||
selectALeaderboardGroup=选择积分榜组...
|
||||
pleaseSelect=请选择
|
||||
requiresValidRegatta=此页面需要有效的比赛、比赛轮次列和船队名称,才能识别显示的比赛轮次。
|
||||
couldNotObtainRace=无法为名称为{0}的比赛获取船队{2}名称为{1}的比赛轮次: {3}
|
||||
errorTryingToCreateEmbeddedMap=尝试创建嵌入式地图出错: {0}
|
||||
@@ -1756,9 +1836,30 @@ eventRegattaHeaderLegendGpsNo=无跟踪数据
|
||||
eventRegattaHeaderLegendWindNo=无风力数据
|
||||
eventRegattaHeaderLegendVideoNo=无视频流
|
||||
eventRegattaHeaderLegendAudioNo=无音频流
|
||||
angleInDegree=角度(度)
|
||||
angleInRadian=角度(弧度)
|
||||
centralAngleInRadian=圆心角(弧度)
|
||||
centralAngleInDegree=圆心角(度)
|
||||
kilometers=千米
|
||||
meters=米
|
||||
nauticalMiles=海里
|
||||
seaMiles=海里
|
||||
geographicalMiles=地理英里
|
||||
days=天
|
||||
hours=小时
|
||||
minutes=分钟
|
||||
seconds=秒
|
||||
milliseconds=毫秒
|
||||
floatNumber=浮点数
|
||||
integer=整数
|
||||
appendResult=附加结果
|
||||
sampleColor=颜色样本
|
||||
sharedSettingsLink=链接与设置
|
||||
leaderboardPage=积分榜页面
|
||||
makeDefault=设为默认值
|
||||
makeDefaultInProgress=正在进行...
|
||||
settingsSavedMessage=当前设置已成功设为默认设置
|
||||
settingsSaveErrorMessage=将设置设为默认设置时发生错误
|
||||
showLiveNow=显示“现在直播”
|
||||
useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=仅使用“开始时间推断”和“从开始和结束时间控制跟踪”中的其中一个
|
||||
unknownLeaderboardType=积分榜类型{0}未知
|
||||
@@ -1770,13 +1871,17 @@ raceRankShort=比赛轮次名次
|
||||
showRaceRankColumn=显示比赛轮次名次
|
||||
estimatedDistance=预计距离
|
||||
estimatedTime=预计时间
|
||||
nothingUpcoming=目前还没有进一步的计划比赛轮次
|
||||
nothingUpcoming=没有即将开始的其他比赛轮次
|
||||
noUpcomingRaceDataAvailable=没有可用的即将进行的比赛轮次数据
|
||||
reallyRemoveSeries=是否确定移除系列赛 "{0}"?注意:随附比赛轮次列的所有比赛轮次日志也将永久移除!
|
||||
settingsId=设置编号
|
||||
documentSettingsId=文档设置编号
|
||||
settingsForId=编号 ''''{0}'''' 的设置
|
||||
userProfileSettingsTabDescription=用户设置由可在页面多个位置找到的设置对话生成。此视图以技术方式为高级用户显示收集的所有设置。请注意,移除的条目无法恢复,请谨慎使用。
|
||||
resetToDefault=重置为默认值
|
||||
resetToDefaultInProgress=正在重置...
|
||||
settingsRemoved=默认设置已恢复
|
||||
settingsRemovedError=无法恢复默认设置
|
||||
userSettingsFilter=设置筛选器
|
||||
requiresRegattaRaceAndLeaderboard=此页面需要有效的比赛名称、比赛轮次名称和积分榜名称。
|
||||
couldNotFindRaceInRegatta=无法为名称为{1}的比赛获取名称为{0}的比赛轮次
|
||||
@@ -1808,6 +1913,7 @@ errorFetchingDimensionData=获取{0}的维度值出错:{1}
|
||||
errorFetchingStatistics=从服务器获取可用统计出错:{0}
|
||||
errorFetchingAggregators=从服务器获取可用聚合器出错:{0}
|
||||
errorLoadingDataRetrieverChainDefinitions=检索可用 DataRetrieverChainDefinitions 出错:{0}
|
||||
errorFetchingComponentsChangedTimepoint=从服务器获取组件更改的时间点出错:{0}
|
||||
errorRunningQuery=运行查询出错:{0}
|
||||
errorReadingWindFixes=读取风力修复{0}出错
|
||||
errorAddingWindFixForRace=添加比赛轮次{0}的风力修复出错:{1}
|
||||
@@ -1881,6 +1987,11 @@ minimumRideHeightInMetersTooltip=将船只视为处于水翼腾空状态所需
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSeconds=相邻水翼腾空段之间的最短持续时间 (s)
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSecondsTooltip=如果不为空,并且两个相邻水翼腾空段之间的时间短于此值,会将这些相邻的水翼腾空段合并成一个。
|
||||
needToProvideValidMinimumRideHeight=您需要提供有效的最小行驶高度值(米)。
|
||||
dataMiningErrorMargins=误差容限
|
||||
elements={0}元素
|
||||
chooseDifferentDimensionTitle=选择不同的维度
|
||||
chooseDifferentDimensionMessage=为分组结果选择不同的维度
|
||||
pleaseSelectADimension=请选择维度
|
||||
currentPortDaggerboardRake=左舷活动披水板倾斜度
|
||||
currentPortDaggerboardRakeTooltip=当前左舷活动披水板倾斜度
|
||||
currentStbdDaggerboardRake=右舷活动披水板倾斜度
|
||||
|
||||
+2
-1
@@ -44,7 +44,8 @@ public class BoatClassVectorGraphicsResolver {
|
||||
BoatClassMasterdata.A_CAT, BoatClassMasterdata.TORNADO, BoatClassMasterdata.FLYING_PHANTOM);
|
||||
BoatClassVectorGraphics keelBoatWithGennaker = new KeelBoatWithGennakerVectorGraphics(BoatClassMasterdata.J70,
|
||||
BoatClassMasterdata.B_ONE, BoatClassMasterdata.J80, BoatClassMasterdata.LASER_SB3, BoatClassMasterdata.LONGTZE,
|
||||
BoatClassMasterdata.RS_FEVA, BoatClassMasterdata.RS_TERA, BoatClassMasterdata.RS100, BoatClassMasterdata.TP52);
|
||||
BoatClassMasterdata.RS_FEVA, BoatClassMasterdata.RS_TERA, BoatClassMasterdata.RS100, BoatClassMasterdata.TP52,
|
||||
BoatClassMasterdata.CLUB_SWAN_50);
|
||||
BoatClassVectorGraphics dinghyWithSpinnaker = new DinghyWithSpinnakerVectorGraphics(BoatClassMasterdata._420,
|
||||
BoatClassMasterdata._470, BoatClassMasterdata._5O5, BoatClassMasterdata.CADET, BoatClassMasterdata.FLYING_DUTCHMAN,
|
||||
BoatClassMasterdata.FOLKBOAT, BoatClassMasterdata.DYAS, BoatClassMasterdata.DRAGON_INT,
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ public class ManeuverTableLifecycle implements ComponentLifecycle<ManeuverTableS
|
||||
|
||||
@Override
|
||||
public String getLocalizedShortName() {
|
||||
return stringMessages.wind();
|
||||
return stringMessages.maneuverTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-6
@@ -13,11 +13,10 @@ public class ManeuverTableSettings extends AbstractGenericSerializableSettings {
|
||||
|
||||
private EnumSetSetting<ManeuverType> selectedManeuverTypes;
|
||||
|
||||
private Iterable<ManeuverType> defaultTypes = Arrays.asList(ManeuverType.values());
|
||||
|
||||
@Override
|
||||
protected void addChildSettings() {
|
||||
selectedManeuverTypes = new EnumSetSetting<>("selectedManeuverTypes", this, defaultTypes,
|
||||
selectedManeuverTypes = new EnumSetSetting<>("selectedManeuverTypes", this,
|
||||
Arrays.asList(ManeuverType.TACK, ManeuverType.JIBE, ManeuverType.PENALTY_CIRCLE),
|
||||
ManeuverType::valueOf);
|
||||
}
|
||||
|
||||
@@ -25,9 +24,6 @@ public class ManeuverTableSettings extends AbstractGenericSerializableSettings {
|
||||
* The default settings
|
||||
*/
|
||||
public ManeuverTableSettings() {
|
||||
selectedManeuverTypes.addValue(ManeuverType.TACK);
|
||||
selectedManeuverTypes.addValue(ManeuverType.JIBE);
|
||||
selectedManeuverTypes.addValue(ManeuverType.PENALTY_CIRCLE);
|
||||
}
|
||||
|
||||
public ManeuverTableSettings(Set<ManeuverType> selectedManeuverTypes) {
|
||||
|
||||
+1
-2
@@ -78,7 +78,6 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint {
|
||||
queryDefinitionProviderWithControls = new QueryDefinitionProviderWithControls(null, null, session,
|
||||
dataMiningService, DataMiningEntryPoint.this, settingsControl, settingsManager,
|
||||
resultsPresenter);
|
||||
queryDefinitionProviderWithControls.getEntryWidget().addStyleName("dataMiningPanel");
|
||||
selectionDockPanel.add(queryDefinitionProviderWithControls.getEntryWidget());
|
||||
queryRunner = new SimpleQueryRunner(null, null, session, dataMiningService, DataMiningEntryPoint.this,
|
||||
queryDefinitionProviderWithControls, resultsPresenter);
|
||||
@@ -89,7 +88,7 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint {
|
||||
* automatic execution of queries. Re-enable this, when this functionality is desired again.
|
||||
*/
|
||||
// settingsControl.addSettingsComponent(queryRunner);
|
||||
SplitLayoutPanel splitPanel = new SplitLayoutPanel(15);
|
||||
SplitLayoutPanel splitPanel = new SplitLayoutPanel(10);
|
||||
splitPanel.addSouth(resultsPresenter.getEntryWidget(), 350);
|
||||
splitPanel.add(selectionDockPanel);
|
||||
return splitPanel;
|
||||
|
||||
+3
-7
@@ -86,20 +86,16 @@ public class NumberPairResultsPresenter extends AbstractSailingResultsPresenter<
|
||||
protected void internalShowResults(QueryResultDTO<?> res) {
|
||||
result = res;
|
||||
createAndAddSeriesToChart();
|
||||
|
||||
for (Entry<GroupKey, ?> resultEntry : result.getResults().entrySet()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
PairWithStats<Number> value = (PairWithStats<Number>) resultEntry.getValue();
|
||||
|
||||
if(value.getIndividualPairs() != null) {
|
||||
for(Pair<Number, Number> pair : value.getIndividualPairs()) {
|
||||
if (value.getIndividualPairs() != null) {
|
||||
for (Pair<Number, Number> pair : value.getIndividualPairs()) {
|
||||
createAndAddPoint(resultEntry.getKey(), pair.getA(), pair.getB());
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
createAndAddPoint(resultEntry.getKey(), value.getAverage().getA(), value.getAverage().getB());
|
||||
}
|
||||
|
||||
}
|
||||
chart.getXAxis().setAxisTitleText(result.getResultSignifier());
|
||||
}
|
||||
|
||||
+6
-6
@@ -7,28 +7,28 @@ import com.sap.sailing.gwt.ui.polarmining.PolarResultsPresenter;
|
||||
import com.sap.sailing.polars.datamining.shared.PolarAggregation;
|
||||
import com.sap.sailing.polars.datamining.shared.PolarBackendData;
|
||||
import com.sap.sse.datamining.shared.data.PairWithStats;
|
||||
import com.sap.sse.datamining.ui.client.presentation.AbstractTabbedResultsPresenter;
|
||||
import com.sap.sse.datamining.ui.client.presentation.TabbedResultsPresenter;
|
||||
import com.sap.sse.datamining.ui.client.presentation.ResultsChart.DrillDownCallback;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
|
||||
public class TabbedSailingResultsPresenter extends AbstractTabbedResultsPresenter {
|
||||
public class TabbedSailingResultsPresenter extends TabbedResultsPresenter {
|
||||
|
||||
|
||||
public TabbedSailingResultsPresenter(Component<?> parent, ComponentContext<?> context,
|
||||
DrillDownCallback drillDownCallback, StringMessages stringMessages) {
|
||||
super(parent, context, drillDownCallback);
|
||||
|
||||
registerResultPresenter(PolarAggregation.class,
|
||||
registerResultsPresenter(PolarAggregation.class,
|
||||
new PolarResultsPresenter(TabbedSailingResultsPresenter.this, getComponentContext(), stringMessages));
|
||||
|
||||
registerResultPresenter(PolarBackendData.class, new PolarBackendResultsPresenter(
|
||||
registerResultsPresenter(PolarBackendData.class, new PolarBackendResultsPresenter(
|
||||
TabbedSailingResultsPresenter.this, getComponentContext(), stringMessages));
|
||||
|
||||
registerResultPresenter(ManeuverSpeedDetailsAggregation.class, new ManeuverSpeedDetailsResultsPresenter(
|
||||
registerResultsPresenter(ManeuverSpeedDetailsAggregation.class, new ManeuverSpeedDetailsResultsPresenter(
|
||||
TabbedSailingResultsPresenter.this, getComponentContext(), stringMessages));
|
||||
|
||||
registerResultPresenter(PairWithStats.class, new NumberPairResultsPresenter(TabbedSailingResultsPresenter.this,
|
||||
registerResultsPresenter(PairWithStats.class, new NumberPairResultsPresenter(TabbedSailingResultsPresenter.this,
|
||||
getComponentContext(), stringMessages));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-11
@@ -777,7 +777,7 @@ public abstract class LeaderboardPanel<LS extends LeaderboardSettings> extends A
|
||||
|
||||
protected abstract void setDefaultRaceColumnSelection(LS settings);
|
||||
|
||||
private void setValuesWithReferenceOrder(Iterable<DetailType> valuesToSet, List<DetailType> referenceOrder,
|
||||
private void setValuesWithReferenceOrder(Iterable<DetailType> valuesToSet, Collection<DetailType> referenceOrder,
|
||||
List<DetailType> collectionToSetValuesTo) {
|
||||
collectionToSetValuesTo.clear();
|
||||
collectionToSetValuesTo.addAll(referenceOrder);
|
||||
@@ -935,11 +935,9 @@ public abstract class LeaderboardPanel<LS extends LeaderboardSettings> extends A
|
||||
*/
|
||||
private class BoatInfoColumn<T> extends LeaderboardSortableColumnWithMinMax<T, String> {
|
||||
private final BoatFetcher<T> boatFetcher;
|
||||
private final CompetitorFetcher<T> competitorFetcher;
|
||||
|
||||
public BoatInfoColumn(CompetitorFetcher<T> competitorFetcher, BoatFetcher<T> boatFetcher, LeaderBoardStyle style) {
|
||||
public BoatInfoColumn(BoatFetcher<T> boatFetcher, LeaderBoardStyle style) {
|
||||
super(new TextCell(), SortingOrder.ASCENDING, LeaderboardPanel.this);
|
||||
this.competitorFetcher = competitorFetcher;
|
||||
this.boatFetcher = boatFetcher;
|
||||
// This style is adding to avoid contained images CSS property "max-width: 100%", which could cause
|
||||
// an overflow to the next column (see https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=3537)
|
||||
@@ -955,12 +953,7 @@ public abstract class LeaderboardPanel<LS extends LeaderboardSettings> extends A
|
||||
@Override
|
||||
public void render(Context context, T object, SafeHtmlBuilder sb) {
|
||||
BoatDTO boat = boatFetcher.getBoat(object);
|
||||
CompetitorDTO competitor = competitorFetcher.getCompetitor(object);
|
||||
boolean boatColorShown = renderBoatColorIfNecessary(competitor, sb);
|
||||
sb.appendEscaped(getShortInfo(boat));
|
||||
if (boatColorShown) {
|
||||
sb.appendHtmlConstant("</div>");
|
||||
}
|
||||
}
|
||||
|
||||
private String getShortInfo(BoatDTO boat) {
|
||||
@@ -3184,9 +3177,8 @@ public abstract class LeaderboardPanel<LS extends LeaderboardSettings> extends A
|
||||
if (getLeaderboardTable().getColumnCount() <= columnIndexWhereToInsertTheNextColumn
|
||||
|| !(getLeaderboardTable()
|
||||
.getColumn(columnIndexWhereToInsertTheNextColumn) instanceof LeaderboardPanel.BoatInfoColumn)) {
|
||||
CompetitorFetcher<LeaderboardRowDTO> competitorFetcher = (LeaderboardRowDTO row) -> row.competitor;
|
||||
BoatFetcher<LeaderboardRowDTO> boatFetcher = (LeaderboardRowDTO row) -> row.boat;
|
||||
BoatInfoColumn<LeaderboardRowDTO> boatInfoColumn = new BoatInfoColumn<LeaderboardRowDTO>(competitorFetcher, boatFetcher, style);
|
||||
BoatInfoColumn<LeaderboardRowDTO> boatInfoColumn = new BoatInfoColumn<LeaderboardRowDTO>(boatFetcher, style);
|
||||
insertColumn(columnIndexWhereToInsertTheNextColumn, boatInfoColumn);
|
||||
}
|
||||
columnIndexWhereToInsertTheNextColumn++;
|
||||
|
||||
-1
@@ -596,7 +596,6 @@ public class RaceBoardPanel
|
||||
|
||||
@Override
|
||||
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
|
||||
leaderboardAndMapViewer.setLeftComponentWidth(leaderboardPanel.getContentPanel().getOffsetWidth());
|
||||
if (editMarkPassingPanel != null) {
|
||||
editMarkPassingPanel.setLeaderboard(leaderboard);
|
||||
}
|
||||
|
||||
+8
-31
@@ -76,8 +76,6 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
private LayoutPanel mainPanel;
|
||||
|
||||
private TouchSplitLayoutPanel splitLayoutPanel;
|
||||
private int savedSplitPosition = -1;
|
||||
private boolean layoutForLeftComponentForcedOnce = false;
|
||||
|
||||
public SideBySideComponentViewer(final Component<?> leftComponentP, final Component<?> rightComponentP,
|
||||
final MediaPlayerManagerComponent mediaPlayerManagerComponent, List<Component<?>> components,
|
||||
@@ -132,18 +130,7 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
this.leftScrollPanel = new ScrollPanel();
|
||||
this.leftScrollPanel.add(leftComponentP.getEntryWidget());
|
||||
this.leftScrollPanel.setTitle(leftComponentP.getEntryWidget().getTitle());
|
||||
this.mainPanel = new LayoutPanel() {
|
||||
@Override
|
||||
public void onResize() {
|
||||
int leftWidth = leftScrollPanel.getOffsetWidth();
|
||||
// The left scroll panel is potentially resized to ensure it is not too wide when the screen gets narrower,
|
||||
// e.g. when resizing browser window or changing mobile device orientation. An offset of 40px is used, so
|
||||
// the panels size slider and its toggle button is always accessable if it is open.
|
||||
savedSplitPosition = Math.min(leftWidth > 0 ? leftWidth : savedSplitPosition, Window.getClientWidth() - 40);
|
||||
splitLayoutPanel.setWidgetSize(leftScrollPanel, savedSplitPosition);
|
||||
super.onResize();
|
||||
}
|
||||
};
|
||||
this.mainPanel = new LayoutPanel();
|
||||
this.mainPanel.setSize("100%", "100%");
|
||||
this.mainPanel.getElement().getStyle().setMarginTop(-12, Unit.PX);
|
||||
this.mainPanel.setStyleName("SideBySideComponentViewer-MainPanel");
|
||||
@@ -154,8 +141,7 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
initializeComponents();
|
||||
|
||||
// initialize the leaderboard component
|
||||
savedSplitPosition = MIN_LEADERBOARD_WIDTH;
|
||||
splitLayoutPanel.insert(leftScrollPanel, leftComponent, Direction.WEST, savedSplitPosition);
|
||||
splitLayoutPanel.insert(leftScrollPanel, leftComponent, Direction.WEST, MIN_LEADERBOARD_WIDTH);
|
||||
|
||||
// create a panel that will contain the horizontal toggle buttons
|
||||
ResizableAbsolutePanel panelForMapAndHorizontalToggleButtons = new ResizableAbsolutePanel();
|
||||
@@ -256,15 +242,12 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
if (!leftComponent.isVisible() && rightComponent.isVisible()) {
|
||||
// the leaderboard is not visible, but the map is
|
||||
if (isWidgetInSplitPanel(leftScrollPanel)) {
|
||||
if (leftScrollPanel.getOffsetWidth() > 0) {
|
||||
savedSplitPosition = Math.min(savedSplitPosition, leftScrollPanel.getOffsetWidth());
|
||||
}
|
||||
splitLayoutPanel.setWidgetVisibility(leftScrollPanel, leftComponent, /* hidden */true,
|
||||
savedSplitPosition);
|
||||
MIN_LEADERBOARD_WIDTH);
|
||||
}
|
||||
} else if (leftComponent.isVisible() && rightComponent.isVisible()) {
|
||||
// the leaderboard and the map are visible
|
||||
splitLayoutPanel.setWidgetVisibility(leftScrollPanel, leftComponent, /* hidden */false, savedSplitPosition);
|
||||
splitLayoutPanel.setWidgetVisibility(leftScrollPanel, leftComponent, /* hidden */false, MIN_LEADERBOARD_WIDTH);
|
||||
} else if (!leftComponent.isVisible() && !rightComponent.isVisible()) {
|
||||
}
|
||||
|
||||
@@ -293,16 +276,6 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void setLeftComponentWidth(int width) {
|
||||
// TODO: The information provided by width is wrong
|
||||
// need to find a way to get the correct information
|
||||
if (!layoutForLeftComponentForcedOnce) {
|
||||
savedSplitPosition = MIN_LEADERBOARD_WIDTH;
|
||||
forceLayout();
|
||||
}
|
||||
layoutForLeftComponentForcedOnce = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserStatusChange(UserDTO user, boolean preAuthenticated) {
|
||||
final Splitter markPassingsSplitter = splitLayoutPanel.getAssociatedSplitter(markPassingsPanel);
|
||||
@@ -364,4 +337,8 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
|
||||
leftScrollPanelSplitter.getToggleButton().setVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
public ScrollPanel getLeftScrollPanel() {
|
||||
return leftScrollPanel;
|
||||
}
|
||||
}
|
||||
+15
-4
@@ -809,16 +809,18 @@ public class TouchSplitLayoutPanel extends DockLayoutPanel {
|
||||
* </p>
|
||||
*
|
||||
* @param hidden set this to true if the panel should be hidden
|
||||
* @param size the size of the panel. Always provide the visible size even when hidden is true.
|
||||
* @param initialSize the size of the panel. only required to be valid if not hidden.
|
||||
*/
|
||||
public void setWidgetVisibility(Widget widget, Component<?> associatedComponentToWidget,
|
||||
final boolean hidden, final int size) {
|
||||
final boolean hidden, final int initialSize) {
|
||||
super.setWidgetHidden(widget, hidden);
|
||||
final Splitter splitter = getAssociatedSplitter(widget);
|
||||
if (splitter != null) {
|
||||
LayoutData layoutData = (LayoutData) widget.getLayoutData();
|
||||
if (hidden) {
|
||||
layoutData.oldSize = layoutData.size;
|
||||
if(layoutData.size > 0) {
|
||||
layoutData.oldSize = layoutData.size;
|
||||
}
|
||||
widget.setVisible(false);
|
||||
if (associatedComponentToWidget != null) {
|
||||
if (associatedComponentToWidget.isVisible()) {
|
||||
@@ -833,7 +835,16 @@ public class TouchSplitLayoutPanel extends DockLayoutPanel {
|
||||
associatedComponentToWidget.setVisible(true);
|
||||
}
|
||||
}
|
||||
splitter.setAssociatedWidgetSize((layoutData.oldSize > 0 ? layoutData.oldSize : size), /* defer */false);
|
||||
if (layoutData.size <= 0) {
|
||||
//it is not yet sized
|
||||
if(layoutData.oldSize > 0) {
|
||||
//and we have a stored old size it had before minimizing it
|
||||
splitter.setAssociatedWidgetSize(layoutData.oldSize, /* defer */false);
|
||||
} else {
|
||||
//and we do not have any size yet, so use the default size
|
||||
splitter.setAssociatedWidgetSize(initialSize, /* defer */false);
|
||||
}
|
||||
}
|
||||
splitter.setDraggerVisible(!hidden);
|
||||
splitter.setVisible(!hidden);
|
||||
splitter.getToggleButton().removeStyleDependentName("Closed");
|
||||
|
||||
+8
-4
@@ -5904,10 +5904,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
Util.addAll(competitorToBoatMappingsRegistered.keySet(), competitorsToUnregister);
|
||||
for (final Entry<CompetitorType, Boat> e : competitorToBoatMappingsRegistered.entrySet()) {
|
||||
CompetitorType competitor = e.getKey();
|
||||
if (competitorToBoatMappingsToRegister.get(competitor) == e.getValue()) {
|
||||
// User wants to map competitor to boat, and that mapping already exists; neither add nor remove this registration but leave as is:
|
||||
competitorToBoatMappingsToRegister.remove(competitor);
|
||||
competitorsToUnregister.remove(competitor);
|
||||
if (competitorToBoatMappingsToRegister.containsKey(competitor)) { // is competitor to be registered?
|
||||
final Boat boatOfCompetitorToRegister = competitorToBoatMappingsToRegister.get(competitor);
|
||||
final Boat boatOfRegisteredCompetitor = e.getValue();
|
||||
if (boatOfCompetitorToRegister == boatOfRegisteredCompetitor) {
|
||||
// User wants to map competitor to boat, and that mapping already exists; neither add nor remove this registration but leave as is:
|
||||
competitorToBoatMappingsToRegister.remove(competitor);
|
||||
competitorsToUnregister.remove(competitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return competitorsToUnregister;
|
||||
|
||||
+14
-12
@@ -266,18 +266,20 @@ public class WindStreamletsRaceboardOverlay extends MovingCanvasOverlay {
|
||||
// confidences
|
||||
for (Entry<WindSource, WindTrackInfoDTO> e : result.windTrackInfoByWindSource.entrySet()) {
|
||||
WindTrackInfoDTO windTrackForSource = windInfoForRace.windTrackInfoByWindSource.get(e.getKey());
|
||||
final WindTrackInfoDTO resultWindTrackInfoDTO = result.windTrackInfoByWindSource.get(e.getKey());
|
||||
windTrackForSource.resolutionOutsideOfWhichNoFixWillBeReturned = resultWindTrackInfoDTO.resolutionOutsideOfWhichNoFixWillBeReturned;
|
||||
if (windTrackForSource.windFixes == null) {
|
||||
windTrackForSource.windFixes = resultWindTrackInfoDTO.windFixes;
|
||||
} else {
|
||||
windTrackForSource.windFixes.addAll(resultWindTrackInfoDTO.windFixes);
|
||||
}
|
||||
if (resultWindTrackInfoDTO.maxWindConfidence > windTrackForSource.maxWindConfidence) {
|
||||
windTrackForSource.maxWindConfidence = resultWindTrackInfoDTO.maxWindConfidence;
|
||||
}
|
||||
if (resultWindTrackInfoDTO.minWindConfidence < windTrackForSource.minWindConfidence) {
|
||||
windTrackForSource.minWindConfidence = resultWindTrackInfoDTO.minWindConfidence;
|
||||
if (windTrackForSource != null) {
|
||||
final WindTrackInfoDTO resultWindTrackInfoDTO = result.windTrackInfoByWindSource.get(e.getKey());
|
||||
windTrackForSource.resolutionOutsideOfWhichNoFixWillBeReturned = resultWindTrackInfoDTO.resolutionOutsideOfWhichNoFixWillBeReturned;
|
||||
if (windTrackForSource.windFixes == null) {
|
||||
windTrackForSource.windFixes = resultWindTrackInfoDTO.windFixes;
|
||||
} else {
|
||||
windTrackForSource.windFixes.addAll(resultWindTrackInfoDTO.windFixes);
|
||||
}
|
||||
if (resultWindTrackInfoDTO.maxWindConfidence > windTrackForSource.maxWindConfidence) {
|
||||
windTrackForSource.maxWindConfidence = resultWindTrackInfoDTO.maxWindConfidence;
|
||||
}
|
||||
if (resultWindTrackInfoDTO.minWindConfidence < windTrackForSource.minWindConfidence) {
|
||||
windTrackForSource.minWindConfidence = resultWindTrackInfoDTO.minWindConfidence;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.sap.sse.datamining.ui.test</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
jarsExcludedFromWebInfLib=
|
||||
warSrcDir=
|
||||
warSrcDirIsOutput=true
|
||||
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
entryPointModules=
|
||||
@@ -0,0 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
pluginProject.extensions=false
|
||||
resolve.requirebundle=false
|
||||
@@ -0,0 +1,15 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Test
|
||||
Bundle-SymbolicName: com.sap.sse.datamining.ui.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Automatic-Module-Name: com.sap.sse.datamining.ui.test
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.junit,
|
||||
com.google.gwt.user;bundle-version="2.8.2",
|
||||
com.sap.sse.datamining.ui,
|
||||
com.sap.sse.gwt;bundle-version="1.0.0",
|
||||
slf4j.api;bundle-version="1.6.4",
|
||||
com.sap.sse.common,
|
||||
com.sap.sse.datamining.shared
|
||||
@@ -0,0 +1,5 @@
|
||||
source.. = src/,\
|
||||
test/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
When updating your version of GWT, you should also update this DTD reference,
|
||||
so that your app can take advantage of the latest GWT module capabilities.
|
||||
-->
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.8.2//EN"
|
||||
"http://gwtproject.org/doctype/2.8.2/gwt-module.dtd">
|
||||
<module rename-to='testssedataminingui'>
|
||||
<!-- Inherit the core Web Toolkit stuff. -->
|
||||
<inherits name='com.google.gwt.user.User'/>
|
||||
|
||||
<!-- Other module inherits -->
|
||||
<inherits name='com.sap.sse.datamining.SSEDataMining'/>
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<source path='client'/>
|
||||
|
||||
<!-- allow Super Dev Mode -->
|
||||
<add-linker name="xsiframe"/>
|
||||
</module>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user