{"__v":9,"_id":"5673027030d9800d003a2eaa","category":{"__v":6,"_id":"56730183547bee0d00997d1a","pages":["5673025a30d9800d003a2ea8","56730268cae8410d008a10b6","5673027030d9800d003a2eaa","567344caf65d9c0d002e3c89","56735274f65d9c0d002e3c9b","5676c05fa7d01d0d0034fa79"],"project":"5672fc989996590d00c22c65","version":"5672fc989996590d00c22c68","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-12-17T18:40:03.307Z","from_sync":false,"order":1,"slug":"beginners","title":"Operation Features"},"project":"5672fc989996590d00c22c65","user":"5654ea8be0d82b0d00ab5747","version":{"__v":7,"_id":"5672fc989996590d00c22c68","project":"5672fc989996590d00c22c65","createdAt":"2015-12-17T18:19:04.699Z","releaseDate":"2015-12-17T18:19:04.699Z","categories":["5672fc999996590d00c22c69","567301169d4c060d009da8b3","56730183547bee0d00997d1a","5673018a06b19d0d0010691b","567301b53054630d00fe9288","567400638565060d009a86fb","5674017bf79ca90d00ad2f67"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.5.0","version":"2.5.0"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-12-17T18:44:00.859Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"Conditions are types, usually structs, which conform to `OperationCondiiton`. They are added to operations just like dependencies and observers.\n\nA silly example would be: \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"operation.addCondition(BlockCondition { \\n    // operation will only be executed if this is true\\n    return trueOrFalse\\n})\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Evaluating conditions\"\n}\n[/block]\nBefore an operation is ready to execute, it will asynchronously *evaluate* all of its conditions. Each condition will return a result of either `.Satisfied` or `.Failed(ErrorType)`. If a condition fails, the operation will finish with an error.\n\nBut wait, there is more...\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Providing a dependency\"\n}\n[/block]\nA condition can also optionally provide an `NSOperation` as a dependency. This operation will automatically be set as a dependency of the operation the condition was attached to. Therefore, given that all dependencies are executed before the operation evaluates its conditions, it means that whatever crucial detail must be set to satisfy the condition can be performed in another operation. This is pretty neat, and underpins much of the framework.\n\nBut wait, there is more...\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Mutual exclusion\"\n}\n[/block]\nA condition can assert whether its operation should be evaluated with mutual exclusion of other instances. This can be very handy for stopping operations from executing. \n\nFor example, if our application presents a modal alert, by executing this in the context of an operation with a mutually exclusive condition, we will prevent any other modal alert from being presented. Given the nature of event based applications this would otherwise be quite tricky. With Operations this can be done like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"let alert = AlertOperation(presentAlertFrom: viewController)\\nalert.title = NSLocaledString(\\\"Hello World\\\", comment: \\\"Hello World\\\")\\nqueue.addOperation(alert)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n`AlertOperation` adds a mutually exclusive condition to itself during its initializer.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Provided conditions\"\n}\n[/block]\nThe framework  comes with a number of operation conditions. Some are simple building blocks, others are more feature rich.\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Condition\",\n    \"h-1\": \"Usage\",\n    \"1-0\": \"`BlockCondition`\",\n    \"1-1\": \"Evaluates based on a `() -> Bool` block.\",\n    \"3-0\": \"`NegatedCondition`\",\n    \"3-1\": \"Evaluates the negation of a composed condition.\",\n    \"5-0\": \"`SilentCondition`\",\n    \"5-1\": \"Suppresses any dependency of a composed condition.\",\n    \"4-0\": \"`NoFailedDependenciesCondition`\",\n    \"4-1\": \"All dependencies must finish without and error or being cancelled.\",\n    \"2-0\": \"`MutuallyExclusive`\",\n    \"2-1\": \"Is always satisfied but forces mutual exclusion around a generic type.\",\n    \"7-0\": \"`RemoteNotificationCondition`\",\n    \"7-1\": \"On iOS, ensures that the user has been prompted to allow remote notifications.\",\n    \"8-0\": \"`UserConfirmationCondition`\",\n    \"8-1\": \"On iOS, will prompt the user to confirm an action via a `UIAlertOperation`. This is great for asking the user to confirm destructive actions.\",\n    \"9-0\": \"`UserNotificationCondition`\",\n    \"9-1\": \"On iOS, ensures that the user has been prompted to allow user notifications.\",\n    \"0-0\": \"`AuthorizedFor`\",\n    \"0-1\": \"Ensures that the user has allowed permission for the app to access a device or account capability. For example, location services.\",\n    \"6-0\": \"`ReachabilityCondition`\",\n    \"6-1\": \"Ensures that the network host is reachable.\"\n  },\n  \"cols\": 2,\n  \"rows\": 10\n}\n[/block]","excerpt":"Conditions (can) prevent Operations from starting","slug":"conditions","type":"basic","title":"Conditions"}

Conditions

Conditions (can) prevent Operations from starting

Conditions are types, usually structs, which conform to `OperationCondiiton`. They are added to operations just like dependencies and observers. A silly example would be: [block:code] { "codes": [ { "code": "operation.addCondition(BlockCondition { \n // operation will only be executed if this is true\n return trueOrFalse\n})", "language": "swift" } ] } [/block] [block:api-header] { "type": "basic", "title": "Evaluating conditions" } [/block] Before an operation is ready to execute, it will asynchronously *evaluate* all of its conditions. Each condition will return a result of either `.Satisfied` or `.Failed(ErrorType)`. If a condition fails, the operation will finish with an error. But wait, there is more... [block:api-header] { "type": "basic", "title": "Providing a dependency" } [/block] A condition can also optionally provide an `NSOperation` as a dependency. This operation will automatically be set as a dependency of the operation the condition was attached to. Therefore, given that all dependencies are executed before the operation evaluates its conditions, it means that whatever crucial detail must be set to satisfy the condition can be performed in another operation. This is pretty neat, and underpins much of the framework. But wait, there is more... [block:api-header] { "type": "basic", "title": "Mutual exclusion" } [/block] A condition can assert whether its operation should be evaluated with mutual exclusion of other instances. This can be very handy for stopping operations from executing. For example, if our application presents a modal alert, by executing this in the context of an operation with a mutually exclusive condition, we will prevent any other modal alert from being presented. Given the nature of event based applications this would otherwise be quite tricky. With Operations this can be done like this: [block:code] { "codes": [ { "code": "let alert = AlertOperation(presentAlertFrom: viewController)\nalert.title = NSLocaledString(\"Hello World\", comment: \"Hello World\")\nqueue.addOperation(alert)", "language": "swift" } ] } [/block] `AlertOperation` adds a mutually exclusive condition to itself during its initializer. [block:api-header] { "type": "basic", "title": "Provided conditions" } [/block] The framework comes with a number of operation conditions. Some are simple building blocks, others are more feature rich. [block:parameters] { "data": { "h-0": "Condition", "h-1": "Usage", "1-0": "`BlockCondition`", "1-1": "Evaluates based on a `() -> Bool` block.", "3-0": "`NegatedCondition`", "3-1": "Evaluates the negation of a composed condition.", "5-0": "`SilentCondition`", "5-1": "Suppresses any dependency of a composed condition.", "4-0": "`NoFailedDependenciesCondition`", "4-1": "All dependencies must finish without and error or being cancelled.", "2-0": "`MutuallyExclusive`", "2-1": "Is always satisfied but forces mutual exclusion around a generic type.", "7-0": "`RemoteNotificationCondition`", "7-1": "On iOS, ensures that the user has been prompted to allow remote notifications.", "8-0": "`UserConfirmationCondition`", "8-1": "On iOS, will prompt the user to confirm an action via a `UIAlertOperation`. This is great for asking the user to confirm destructive actions.", "9-0": "`UserNotificationCondition`", "9-1": "On iOS, ensures that the user has been prompted to allow user notifications.", "0-0": "`AuthorizedFor`", "0-1": "Ensures that the user has allowed permission for the app to access a device or account capability. For example, location services.", "6-0": "`ReachabilityCondition`", "6-1": "Ensures that the network host is reachable." }, "cols": 2, "rows": 10 } [/block]