ライブラリは、以前に開発したプログラムコードをさまざまなプログラムで使用できるという点で優れています。 したがって、プログラマは、標準機能の一部としてライブラリの一部である既製のソリューションを使用することにより、作業を大幅に簡素化し、実行時間を短縮できます。 この記事では静的ライブラリのみが考慮され、そのコードはコンパイル時に実行可能ファイルに完全に含まれているため、プログラムを簡単に移植できます。
ライブラリを「ゼロから」作成し、すでに完了したプロジェクトの機能の一部をライブラリに組み込むことを考慮して、問題をより詳細かつ体系的にカバーしようとしました。 クロスプラットフォームまたは汎用性とは、i386またはx86_64アーキテクチャーのプロセッサー上で実行されているシミュレーターと、実際のデバイスとのライブラリーの互換性を意味します。
1.ライブラリプロジェクトを作成する
ライブラリを開発する場合、開発者は2つの方法を使用できます。1つ目-ライブラリをゼロから作成する方法、2つ目-ライブラリを作成するベースとなる機能がプロジェクトにあります。 両方を検討してください。
図書館作成「ゼロから」
アクションのシーケンスは、新しいプロジェクトを作成するときと同じです。
ファイル>新規>プロジェクト... iOS>フレームワークとライブラリ> Cocoa Touch Static Library 名前を設定します(例-MySecretLibrary)
これを行う方法の詳細については、こちらをご覧ください↓
図 1-1
図 1-2
図 1-3
ステップ1 ファイル>新規>プロジェクト...
図 1-1
ステップ2 Cocoa Touch Static Libraryの選択
図 1-2
ステップ3 ライブラリー名(製品名)の割り当て...
図 1-3
プロジェクトウィンドウは次のようになります。
図1-4
別のプロジェクトの機能部から作成されたライブラリ
既製のMyAppプロジェクトがあり、それに含まれるいくつかのクラスに基づいてライブラリを作成するとします。 プロジェクトウィンドウは次のようになります。
図 2-0
静的ライブラリの新しいターゲットを作成します。
アクションのシーケンスは、新しいライブラリを最初から作成するときのシーケンスに似ています。
ファイル>新規> Targect ... iOS>フレームワークとライブラリ> Cocoa Touch Static Library 名前を設定します(例-MySecretLibrary)
これを行う方法の詳細については、こちらをご覧ください↓
図 1-1
図 1-2
図 1-3
ステップ1 ファイル>新規>ターゲット...
図 1-1
ステップ2 Cocoa Touch Static Libraryの選択
図 1-2
ステップ3 ライブラリー名(製品名)の割り当て...
図 1-3
プロジェクトウィンドウは次のようになります。
図 1-4
MySecretLibraryファイルを含む新しいターゲットとフォルダーがプロジェクトに表示されたことがわかります。
2.ライブラリアーキテクチャを構成する
デフォルトでは、アプリケーション構成にはarmv7およびarm64のアセンブリが含まれています。 armv7s(iPhone 5、iPhone 5c、iPad 2012用)を追加できます。たとえば、armv6とi386も追加できます。 それはすべて、ライブラリが動作するはずのプラットフォームに依存します。
参考までに。 過去のさまざまなAppleデバイスで使用されているプラットフォームの表
図 5
3.ビルドフェーズの構成
コンパイルファイルの追加
ビルドフェーズ> Compliteソース
デフォルトでは、MySecretLibrary.mファイルがコンパイル用に含まれています。 私たちのタスクは、ユーティリティ調達ファイル(.h)、リソースなどを含む、ライブラリが機能するために必要なすべてのファイルを追加することです。
図 6-1
ヘッダーファイルの追加
ビルドフェーズ>ファイルのコピー
デフォルトでは、ファイルMySecretLibrary.hが含まれています。 ライブラリを新しいプロジェクトに接続するために必要なすべてのヘッダーファイルを追加する必要があります。
各ライブラリには、このライブラリに含まれるすべての関数のプロトタイプ(宣言)を記述するヘッダーファイルが必要であることを思い出してください。 ライブラリはヘッダーファイルを使用して、プログラムコードにその中に存在する関数とその使用方法を伝えます。
重要! さまざまなクラスと関数の宣言を含むヘッダーファイルがいくつかある場合、それらをすべて別々に新しいプロジェクトに接続することは望ましくありません。 ライブラリの1つの見出しファイルを作成し、他のすべてのファイルをそれに接続すると便利です。 たとえば、Foundationなどの標準フレームワークのヘッダーファイルは次のようになります。
財団ヘッダー
/* Foundation.h Copyright (c) 1994-2015, Apple Inc. All rights reserved. */ #include <CoreFoundation/CoreFoundation.h> #import <Foundation/NSObjCRuntime.h> #import <Foundation/NSArray.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSBundle.h> #import <Foundation/NSByteOrder.h> #import <Foundation/NSCalendar.h> #import <Foundation/NSCharacterSet.h> #import <Foundation/NSCoder.h> #import <Foundation/NSData.h> #import <Foundation/NSDate.h> #import <Foundation/NSDateFormatter.h> #import <Foundation/NSDateIntervalFormatter.h> #import <Foundation/NSMassFormatter.h> #import <Foundation/NSLengthFormatter.h> #import <Foundation/NSEnergyFormatter.h> #import <Foundation/NSPersonNameComponents.h> #import <Foundation/NSPersonNameComponentsFormatter.h> #import <Foundation/NSDecimal.h> #import <Foundation/NSDecimalNumber.h> #import <Foundation/NSDictionary.h> #import <Foundation/NSEnumerator.h> #import <Foundation/NSError.h> #import <Foundation/NSException.h> #import <Foundation/NSFileHandle.h> #import <Foundation/NSFileManager.h> #import <Foundation/NSFormatter.h> #import <Foundation/NSHashTable.h> #import <Foundation/NSHTTPCookie.h> #import <Foundation/NSHTTPCookieStorage.h> #import <Foundation/NSIndexPath.h> #import <Foundation/NSIndexSet.h> #import <Foundation/NSInvocation.h> #import <Foundation/NSJSONSerialization.h> #import <Foundation/NSKeyValueCoding.h> #import <Foundation/NSKeyValueObserving.h> #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSLocale.h> #import <Foundation/NSLock.h> #import <Foundation/NSMapTable.h> #import <Foundation/NSMethodSignature.h> #import <Foundation/NSNotification.h> #import <Foundation/NSNotificationQueue.h> #import <Foundation/NSNull.h> #import <Foundation/NSNumberFormatter.h> #import <Foundation/NSObject.h> #import <Foundation/NSOperation.h> #import <Foundation/NSOrderedSet.h> #import <Foundation/NSOrthography.h> #import <Foundation/NSPathUtilities.h> #import <Foundation/NSPointerArray.h> #import <Foundation/NSPointerFunctions.h> #import <Foundation/NSPort.h> #import <Foundation/NSProcessInfo.h> #import <Foundation/NSPropertyList.h> #import <Foundation/NSProxy.h> #import <Foundation/NSRange.h> #import <Foundation/NSRegularExpression.h> #import <Foundation/NSRunLoop.h> #import <Foundation/NSScanner.h> #import <Foundation/NSSet.h> #import <Foundation/NSSortDescriptor.h> #import <Foundation/NSStream.h> #import <Foundation/NSString.h> #import <Foundation/NSTextCheckingResult.h> #import <Foundation/NSThread.h> #import <Foundation/NSTimeZone.h> #import <Foundation/NSTimer.h> #import <Foundation/NSURL.h> #import <Foundation/NSURLAuthenticationChallenge.h> #import <Foundation/NSURLCache.h> #import <Foundation/NSURLConnection.h> #import <Foundation/NSURLCredential.h> #import <Foundation/NSURLCredentialStorage.h> #import <Foundation/NSURLError.h> #import <Foundation/NSURLProtectionSpace.h> #import <Foundation/NSURLProtocol.h> #import <Foundation/NSURLRequest.h> #import <Foundation/NSURLResponse.h> #import <Foundation/NSUserDefaults.h> #import <Foundation/NSValue.h> #import <Foundation/NSValueTransformer.h> #import <Foundation/NSXMLParser.h> #import <Foundation/NSZone.h> #import <Foundation/FoundationErrors.h> #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) #import <Foundation/NSAttributedString.h> #import <Foundation/NSByteCountFormatter.h> #import <Foundation/NSCache.h> #import <Foundation/NSComparisonPredicate.h> #import <Foundation/NSCompoundPredicate.h> #import <Foundation/NSDateComponentsFormatter.h> #import <Foundation/NSExpression.h> #import <Foundation/NSExtensionContext.h> #import <Foundation/NSExtensionItem.h> #import <Foundation/NSExtensionRequestHandling.h> #import <Foundation/NSFileCoordinator.h> #import <Foundation/NSFilePresenter.h> #import <Foundation/NSFileVersion.h> #import <Foundation/NSFileWrapper.h> #import <Foundation/NSItemProvider.h> #import <Foundation/NSLinguisticTagger.h> #import <Foundation/NSMetadata.h> #import <Foundation/NSMetadataAttributes.h> #import <Foundation/NSNetServices.h> #import <Foundation/NSPredicate.h> #import <Foundation/NSProgress.h> #import <Foundation/NSUbiquitousKeyValueStore.h> #import <Foundation/NSUndoManager.h> #import <Foundation/NSURLSession.h> #import <Foundation/NSUserActivity.h> #import <Foundation/NSUUID.h> #endif #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || TARGET_OS_WIN32 #import <Foundation/NSArchiver.h> #import <Foundation/NSBackgroundActivityScheduler.h> #import <Foundation/NSCalendarDate.h> #import <Foundation/NSConnection.h> #import <Foundation/NSDistantObject.h> #import <Foundation/NSDistributedNotificationCenter.h> #import <Foundation/NSGeometry.h> #import <Foundation/NSPortCoder.h> #import <Foundation/NSPortMessage.h> #import <Foundation/NSPortNameServer.h> #import <Foundation/NSProtocolChecker.h> #import <Foundation/NSTask.h> #import <Foundation/NSXMLDTD.h> #import <Foundation/NSXMLDTDNode.h> #import <Foundation/NSXMLDocument.h> #import <Foundation/NSXMLElement.h> #import <Foundation/NSXMLNode.h> #import <Foundation/NSXMLNodeOptions.h> #import <Foundation/NSURLDownload.h> #import <Foundation/NSURLHandle.h> #endif #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) #import <Foundation/NSAffineTransform.h> #import <Foundation/NSAppleEventDescriptor.h> #import <Foundation/NSAppleEventManager.h> #import <Foundation/NSAppleScript.h> #import <Foundation/NSClassDescription.h> #import <Foundation/NSDistributedLock.h> #import <Foundation/NSGarbageCollector.h> #import <Foundation/NSHFSFileTypes.h> #import <Foundation/NSHost.h> #import <Foundation/NSObjectScripting.h> #import <Foundation/NSScriptClassDescription.h> #import <Foundation/NSScriptCoercionHandler.h> #import <Foundation/NSScriptCommand.h> #import <Foundation/NSScriptCommandDescription.h> #import <Foundation/NSScriptExecutionContext.h> #import <Foundation/NSScriptKeyValueCoding.h> #import <Foundation/NSScriptObjectSpecifiers.h> #import <Foundation/NSScriptStandardSuiteCommands.h> #import <Foundation/NSScriptSuiteRegistry.h> #import <Foundation/NSScriptWhoseTests.h> #import <Foundation/NSSpellServer.h> #import <Foundation/NSUserNotification.h> #import <Foundation/NSUserScriptTask.h> #import <Foundation/NSXPCConnection.h> #endif
図 6-2
既製のアプリケーションからライブラリを作成する場合、同じ手順を実行してビルドフェーズを構成する必要があります。 Compliteサワーおよびファイルのコピーには、同じ名前のターゲットによって作成されたMySecretLibraryグループのファイルだけでなく、アプリケーションの他のリソースも含めることができることを理解してください。 MySecretLibraryグループは、たとえば、アプリケーションの特定のクラスと機能のみをそこにあるファイルに転送するなど、操作する機会を与えるためにのみ作成されます。 Xcodeのコンパイル時に、この特定のターゲットのビルドフェーズで指定されたファイルのみを使用することを思い出してください。 つまり、上記の例では、MySecretLibraryフォルダーのファイルのみがコンパイルされます。
原則として、この段階で、すべての準備作業が完了し、図書館の組み立てを開始できます...しかし、微妙な点が1つあります。 実際、Xcodeは、コンピューターで実行されているシミュレーターのアーキテクチャーi386またはx86_64のプロセッサー、またはプロセッサーがアーキテクチャーarmv7、armv7sまたはarmv64を備えている可能性が高いデバイスのいずれかの現在の設定に基づいて製品をコンパイルします。 したがって、シミュレータ用にコンパイルされたライブラリは実際のデバイスでは機能しません。逆の場合、デバイス用にコンパイルされたライブラリはシミュレータでは機能しません。
シミュレーター用のコンパイル
ライブラリターゲットを「アクティブスキーム」として設定-MySecretLibrary、MySecretLibrary> iPhone 6sなどのシミュレーターを選択します
図 7-1
そしてBを押してライブラリプロジェクトをコンパイルします。
結果は写真のようになります。
図 7-2
赤のファイル名libMySecretLibrary.aが黒に変わったこと、つまり、コンパイルが成功し、ファイルがコンピューターに保存されたことに注意してください。 右クリックすると、メニューが表示され、[Finderに表示]項目を選択します。
図 7-3
開いたウィンドウに、ライブラリファイル-libMySecretLibrary.aおよび調達ファイル-MySecretLibrary.hがあるDebug-iphonesimulatorフォルダーが表示されます。
図 7-4
上記のフォルダーに移動すると、シミュレーター用に収集されたライブラリーのフォルダーがProductsフォルダーにあることが明確になります。
図 7-5
この場合のDebug-iphonesimulatorフォルダーへのフルパス:
/ユーザー/ [userName] /ライブラリ/開発者/ Xcode / DerivedData / MySecretLibrary-esufqblgaisjjeecltzoxyiyogzj /ビルド/製品/ Debug-iphonesimulator
デバイス用のコンパイル
ライブラリターゲットを「アクティブスキーム」として設定します-MySecretLibrary、「Generic iOS Device」(MySecretLibrary> Generic iOS Device)を選択します
図 8-1
そしてBを押してライブラリプロジェクトをコンパイルします。
図 8-2
「Finderで表示」を選択します。
図 8-3
ライブラリフォルダーに移動します。 前のものと似ていますが、ライブラリファイルlibMySecretLibrary.aはデバイスのアーキテクチャ用にコンパイルされています。
図 8-4
製品フォルダは次のようになります。
図 8-5
この場合のDebug-iphoneosフォルダーへのフルパス:
/ユーザー/ [userName] /ライブラリ/開発者/ Xcode / DerivedData / MySecretLibrary-esufqblgaisjjeecltzoxyiyogzj /ビルド/製品/ Debug-iphoneos
Productsフォルダには、シミュレータ用とデバイス用の2つのライブラリがあることがわかります。
次のステップは、ライブラリの両方のバージョンを結合する1つのバイナリファイルを作成することです。
4.ユニバーサルバイナリファイルを生成する
ユニバーサルバイナリファイルを作成するためのオプションはかなりありますが、すべての場合、本質は3つの連続したアクションに要約されます。
-デバイス用のライブラリを生成します
-シミュレーター用のライブラリーを生成する
-ライブラリを結合し、lipoコマンドを使用してバイナリファイルを作成します
興味のある方のために、リポ↓コマンドの詳細を説明します。
リポ ユニバーサルファイルを作成または操作します:ユニバーサルバイナリを単一のアーキテクチャファイルに、またはその逆に変換します。 構文 lipo [input_file] ... [-arch arch_type input_file] ... [-arch_blank arch_type] ... {-info | -detailed_info} [-output output_file]操作 [-segalign arch_type値] Operationは次のいずれかです。 [-create] [-arch_blank arch_type] [-thin arch_type] [-extract arch_type] ... [-extract_family arch_type] ... [-remove arch_type] ... [-replace arch_type file_name] ... [-verify_arch arch_type ...] オプション -info入力ユニバーサルファイルのアーキテクチャタイプを簡単にリストします。 各アーカイブの名前をリストします。 -detailed_info 入力ユニバーサルファイルのアーキテクチャタイプの詳細なリストを表示します。 汎用ヘッダー情報をリストします。 ファイル内のアーキテクチャごとに。 -arch arch_type input_file input_fileに指定されたアーキテクチャタイプが含まれていることをlipoに伝えます。 input_fileがオブジェクトファイル、ユニバーサルファイルの場合、これは不要です。 または、アーキテクチャー(複数可)リポが把握できる他のファイル。 -arch_blank arch_type 指定されたarch_typeの出力は、MH_DYLIB_STUBファイルになります。 このフラグは、-create以外の操作では使用できません。 -output output_file 出力ファイル。 -作成 入力ファイルから1つのユニバーサル出力ファイルを作成します。 -thin arch_type 1つの入力ファイルを取得し、指定されたarch_typeを使用してシン出力ファイルを作成します。 -arch_type file_nameを置き換えます 1つのユニバーサル入力ファイルを取得します。 出力ファイルで、arch_typeの内容を置き換えます 入力ファイルと指定されたfile_nameの内容。 -arch_typeを削除 1つのユニバーサル入力ファイルを取得し、そのユニバーサルファイルからarch_typeを削除します。 結果を出力ファイルに配置します。 -extract arch_type 1つのユニバーサル入力ファイルを取得し、そのユニバーサルファイルからarch_typeを そのアーキテクチャのみを含むユニバーサル出力ファイル。 -extract_family arch_type 1つの汎用入力ファイルを取得し、そのファミリのすべてのarch_typesをコピーします arch_typeは、そのユニバーサルファイルから、それらのみを含む出力ファイルになります アーキテクチャ。 アーキテクチャが1つだけ見つかった場合、ファイルは薄くなります。 -verify_arch arch_type ... 1つの入力ファイルを取得し、指定されたarch_typesがファイルに存在することを確認します。 その場合は、ステータス0で終了し、そうでない場合はステータス1で終了します。 -segalign arch_type値 ユニバーサルファイルを作成するときに、指定されたarch_typeのセグメントアラインメントを設定します そのアーキテクチャを含む。 値は16進数であり、 整数2の累乗。これは、リポがアライメントを把握できない場合にのみ必要です。 入力ファイル(現在はオブジェクトファイルではありません)、または あまりにも保守的に整列。 lipoが認識しないファイルのデフォルトは0です (2 ^ 0、または1バイトのアライメント)、およびアーカイブのデフォルトのアライメント 4(2 ^ 2、または4バイトのアライメント)です。 arch_typeサポートされているアーキテクチャ名:i386(32ビットIntel)ppc(32ビットpowerpc) ppc64(64ビットpowerpc)またはx86_64(64ビットIntel) lipoは1つの出力ファイルを生成し、入力ファイルを変更しません。 リポは次のことができます:ユニバーサルファイルにアーキテクチャタイプをリストします。 1つ以上の入力ファイルから単一のユニバーサルファイルを作成します。 単一のユニバーサルファイルを指定された1つのアーキテクチャタイプに間引きます。 入力ファイルからアーキテクチャタイプを抽出、置換、削除して、単一の新しいユニバーサル出力ファイルを作成します。 例 $ cd /アプリケーション $ lipo Stickies.app/Contents/MacOS/Stickies -info $ lipo Stickies.app/Contents/MacOS/Stickies -thin i386 -output Stickies.app/Contents/MacOS/Stickies.i386 $ cd Stickies.app/Contents/MacOS/ $ rmスティッキーズ $ mv Stickies.i386スティッキーズ
さまざまなコマンド(コマンドライン)の詳細については、SS64.comをご覧ください。
ユニバーサルバイナリライブラリファイルの作成
-デバイス用のライブラリをコンパイルします(上記のとおり)
-シミュレーター用のライブラリーをコンパイルします(上記のとおり)
-オープンターミナル
-ターミナルの製品フォルダーに移動します(cdコマンドとフォルダーパス)
-次のテキストを入力します。
lipo -create Debug-iphoneos/libMySecretLibrary.a Debug-iphonesimulator/libMySecretLibrary.a -output libMySecretLibrary_combined.a
その結果、ユニバーサルフォルダーファイルlibMySecretLibrary_combined.aがProductsフォルダーに保存されます。 ヘッダーファイルは、Debug-iphoneosまたはDebug-iphonesimulatorフォルダーから使用できます。
図 9-0
当然、libMySecretLibraryの代わりに、コードでライブラリの名前を使用する必要があります。
実際、タスクは完了しています。 ただし、Xcodeは多くのプロセスを自動化するツールを提供します。特に、Aggregateターゲットを使用してライブラリの作成とアセンブリを自動化できます。
プロジェクトに新しいターゲットを追加-集計
Xcodeには、必要ではない特別なターゲティングパターンがあります
特定のタイプの製品に対応します。 これらは、以下に使用できる特別な集約ターゲットです。
-ターゲットグループの関連付け
-ファイルシステムの特定の場所にファイルをコピーする
-外部ビルドシステムを使用した製品の作成
-コマンドスクリプトを実行する
この場合、 コマンドスクリプトを実行するためのターゲットを作成します。このスクリプトを使用して、シミュレータ用とデバイス用の2つのレイヤーを組み合わせたユニバーサルライブラリをアセンブルします。
アクションのシーケンスは、他のターゲットを追加する場合と同じです。
ファイル>新規> Targect ... その他(OS Xの一番下)>集計 名前を設定します(たとえば、MySecretLibrary_combined)
これを行う方法の詳細については、こちらをご覧ください↓
図 9-1
図 9-2
図 9-3
ステップ1 ファイル>新規>ターゲット...
図 9-1
ステップ2 [その他]> [集計]を選択します
図 9-2
ステップ3 ライブラリー名(製品名)の割り当て...
図 9-3
その後、プロジェクトウィンドウは次のようになります。
図 9-4
CONFIGURE AGGREGATE(コマンドスクリプトを配置するフォームを追加)
集計ターゲットを選択し、セクション>ビルドフェーズに進み、「+」をクリックします
図 10-1
開いたメニューで、>新規スクリプト実行フェーズを選択します
図 10-2
ライブラリのアセンブリを制御するスクリプトを配置するフォームが開きます。
プロジェクトウィンドウは次のようになります(矢印はスクリプトを配置する場所を示します)。
図 10-3
チームスクリプトを追加
ユニバーサルライブラリを作成するためのコマンドスクリプト:
BUILD_TARGET_DIR=$PROJECT_DIR/build xcodebuild -target $PROJECT_NAME -sdk "iphonesimulator" -configuration "Release" clean build xcodebuild -target $PROJECT_NAME -sdk "iphoneos" -configuration "Release" clean build lipo -create -output "$BUILD_TARGET_DIR/$PROJECT_NAME-Combined.a" "$BUILD_TARGET_DIR/Release-iphoneos/lib$PROJECT_NAME.a" "$BUILD_TARGET_DIR/Release-iphonesimulator/lib$PROJECT_NAME.a"
このスクリプトは、同じ3つの単純なアクションの実行を自動化することがわかります。
-シミュレーターのライブラリーを生成します
-デバイスのライブラリを生成します
-ライブラリをマージし、lipoコマンドを使用してバイナリファイルを作成します
このスクリプトをコピーして、[スクリプトの実行]フォームに追加します。
図 10-4
ターゲットを集合MySecretLibraryとして設定します
図 10-5
ライブラリプロジェクトをコンパイルするには、⌘Bを押します。
その結果、プロジェクトのフォルダー(Products!フォルダーではありません)に、生成されたすべてのファイルがあるビルドフォルダーが表示されます。
図 10-6
実際、それがすべてです。 ご覧のとおり、この質問はほんの数行の簡単なコードで解決されます。
この記事以外にも、関連するリソースの重複を排除し、アプリケーションに既にインストールされているライブラリを更新することに関連する質問がありました。 最近、CocoaPodsなどの依存関係管理システムが非常に一般的になりました。 このようなシステムの使用は議論の余地のある問題です。 一方では、リソースの重複を回避し、既製のアプリケーションでライブラリの現在のバージョンを維持することが可能になります。 一方、ライブラリが保存され、サードパーティに属するリポジトリに完全に依存しています。さらに、ライブラリの新しいバージョンが以前のものと完全に互換性がない場合、アプリケーションがクラッシュする可能性があります。
この資料がお役に立てば幸いです。MSLibraryfor iOSチーム
その他の記事:
iOSなどの正規表現を使用した電話番号のキャプチャと検証...パート1
iOSなどの正規表現を使用した電話番号のキャプチャと検証...パート2
iOSなどで、ビットマスクを使用して複数の条件を実装する...
簡単:iOSなどの正規表現を使用して、文字列から不要な文字を削除します...