#モバイルアプリ

タスクマネージャー—非同期iOS開発用のツール

サラ・ゲチによるイラスト

タスクマネージャーの紹介—iOSアプリを開発する際の非同期操作の管理を容易にするためにShakuroiOS開発者によって開発されたSwiftライブラリ。Task Managerコンポーネントの主な目的は、サーバー、データベース、およびその他のバックグラウンド操作での作業をユニットのような操作またはタスクにカプセル化することです。これは、ビジネスロジックをUIから分離し、アプリ全体で操作を再利用するのに役立ちます。それがどのように機能し、iOS開発者にとってどのように役立つかを正確に見てみましょう。

それは何についてであり、それがどのように機能するか

通常、アプリのアーキテクチャを設計するとき、iOS開発者は操作のフローとそれらの間の依存関係を制御する方法を考える必要があります。特定のプロジェクトに最適なソリューションを見つけるのは、実際には開発者次第です。非同期操作は、同時に実行できる場合に物事がどのように結びつくかというセマンティクスのため、複雑なトピックです。一部の開発者は、操作の依存関係を管理するためにシングルトンネットワークマネージャーを使用し、1つのクラスですべてのサーバーリクエストを記述します。このようなアプローチの主な問題は、エンドポイント、本体、パラメーターを含む各サービス呼び出しが含まれ、各呼び出しの成功と失敗を処理するため、シングルトンクラスの責任が多すぎることです。

タスクマネージャーは、この問題に対する私たちのソリューションです。何年にもわたって、Shakuroはますます複雑なiOSアプリに取り組んできました。そのため、私たちのチームは、iOSの開発をより簡単かつ迅速に行えるツールを考案することに忙しくしていました。このようなツールの例の1つは、非同期タスクの作業を簡素化して開発時間を短縮し、コストを削減するタスクマネージャーライブラリです。

作業を最適化し、コードをより小さな要素に分割し、それらの依存関係と優先順位を設定できるようにします。

タスクマネージャーを使用すると、サーバー通信の動作方法とデータの受信および保存方法を説明する個別の操作を作成し、それらの間に基本的な依存関係を構築して、後でより複雑な作業を行うときに、これらを面倒に説明する必要がないようにすることができます。何度も何度も基本的な接続。

たとえば、eコマースアプリの開発中に、いくつかの記事の読み込みを伴う操作が必要であると想像してください。ただし、それが機能するには、関連するカテゴリを最初にロードする必要があります。タスクマネージャを使用して、「記事の操作」と「カテゴリの操作」の依存関係を事前に指定します。これにより、記事を読み込むときに、カテゴリが最初に自動的に読み込まれます。

結果:

  • より複雑なアーキテクチャで作業する場合でも複雑さが軽減されます
  • よりクリーンなコード
  • エラーが少ない
  • より高速なプロセス
  • コスト削減。

言い換えれば、タスクマネージャーで:

  1. 独自の操作を作成して、作業要素をより小さなクラスに分割し、それらを別々のロジックユニットにカプセル化することができます。それはあなたのコードをより再利用可能で安定させます。
  2. 操作間の依存関係を簡単に解決できるため、iOS開発プロセスが大幅に便利になります。
  3. タスクマネージャを使用すると、操作で型指定された結果が返され、配列とオブジェクトの型に関連して発生する可能性のあるエラーを回避できます。
  4. 非同期操作を再試行できます。操作で失敗した場合は、すべてのコードを手動で記述して他のすべての操作で繰り返すことなく、結果を分析し、発生したエラーの種類に応じて条件を追加して操作を再試行できます。
  5. 透明で柔軟性があり、使いやすいツールを手に入れることができます。

クイックスタート

  • タスクマネージャーの作成(ここではHTTPClientを使用します):
  • Internal class ExampleTaskManager: TaskManager {
        private let randomOrgClient: HTTPClient
        init(name: String,
             qualityOfService: QualityOfService,
             maxConcurrentOperationCount: Int,
             randomOrgClient: HTTPClient) {
            self.randomOrgClient = randomOrgClient
            super.init(name: name,
                       qualityOfService: qualityOfService,
                       maxConcurrentOperationCount: maxConcurrentOperationCount)
        }
        internal func doFirstOperation() -> Task<Int> {
            return performOperation(operationType: FirstOperation.self, options: ExampleOperationOptions())
        }
    }
    

    class FirstOperation: BaseOperation<Int, ExampleOperationOptions> {
        override func main() {
            let numberOfSteps: Int = 10
            for index in 1...numberOfSteps {
                print("FirstOperation: substep #\(index) / \(numberOfSteps)")
                Thread.sleep(forTimeInterval: 0.5)
                if isCancelled {
                    break
                }
            }
            if isCancelled {
                finish(result: .cancelled)
            } else {
                finish(result: .success(result: numberOfSteps))
            }
        }
        internal override var priorityValue: Int {
            return 0
        }
        internal override var priorityType: OperationPriorityType {
            return OperationPriorityType.fifo
        }
    }
    

    internal class ExampleTaskManagerViewController: UIViewController {
        private let taskManager: ExampleTaskManager
        required init?(coder aDecoder: NSCoder) {
            let randomOrgClient = HTTPClient(name: "RandomOrgClient")
                    
            taskManager = ExampleTaskManager(
                name: "com.shakuro.iOSToolboxExample.ExampleTaskManager",
                qualityOfService: QualityOfService.utility,
                maxConcurrentOperationCount: 6,
                randomOrgClient: randomOrgClient)
                    
            super.init(coder: aDecoder)
        }
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        @IBAction private func operationButton1Tapped() {
            let task = taskManager.doFirstOperation()
            task.onComplete(queue: DispatchQueue.main, closure: { (_, result) in
                print("operationButton1Tapped() completion. result: \(result)")
            })
        }
    }
    

タスクマネージャーライブラリの詳細については、GitHubをご覧ください。READMEに従って、iOS開発のより簡単で効果的なプロセスをお楽しみください。

セルゲイポポフとケイトショクロバ脚本の作品

もともとhttps://shakuro.comで公開されました。

提案された投稿

コード化可能: 不正な列挙値の処理

コード化可能: 不正な列挙値の処理

コードベースの保護: 予期しない列挙値の処理 アプリがどこからともなくクラッシュし始めた状況に直面したことはありませんか?調査の結果、バックエンドがコードの列挙内に存在しない特定の列挙ベースのフィールドに値を提供したことが判明しましたか? 次の例を考えてみましょう: Ohhh I love some Tea しかし、JSON データの favouriteBeverage を Tea から Juice (列挙型 Beverage 内に存在しない値) に変更するとどうなるでしょうか? メッセージの「無効な文字列値 Juice から Beverage を初期化できません」という部分に注目してください。これが Playground コードではなく実際のアプリであった場合、アプリはクラッシュしていたでしょう。では、バックエンドが応答で無効な値を送信した場合でも、アプリが完全にクラッシュするのではなく、それを処理できるようにするにはどうすればよいでしょうか? 方法の 1 つで、私の個人的なお気に入りは次のとおりです。

ジュニア iOS 開発者向けの必須スキル: 総合ガイド

ジュニア iOS 開発者向けの必須スキル: 総合ガイド

この包括的なガイドでは、ジュニア iOS 開発者に必要な基本的なスキルについて説明します。Swift や Objective-C などのプログラミング言語から、コラボレーションやコミュニケーションまで、今日の競争の激しい市場で成功するためにジュニア iOS 開発者が知る必要があるすべてをカバーします。

関連記事

脅威ハンティングのための OSINT の収集

脅威ハンティングのための OSINT の収集

サイバー愛好家の皆さん、こんにちは!OSINT for Threat Hunting シリーズへようこそ。最初の記事では、OSINT の概要と脅威ハンティングにおけるその重要性について説明しました。

ドメイン名に関する情報の検索

Brian P. Hogan 著『Small, Sharp Software Tools』からの抜粋

ドメイン名に関する情報の検索

facebook.com にリクエストを送信すると、コンピュータはドメイン名を検索してそのドメイン名を IP アドレスに変換し、コンピュータが接続できるようにします。

無限の命

大人になると、世界はそういうもので、あなたの人生はただ世界の中で生きていくだけで、決して命を危険にさらすことはなく、決められた道をたどって最後には死ぬだけで、失敗しないように努めるのだと言われがちです。壁を打ちすぎてはいけません。しかし、それは非常に限られた人生です。

ジャーナル・アウトバート

ジャーナル・アウトバート

日記を開く: 1 日 1 枚の写真。私はいつも物語に魅了されてきました。