1. Continue integration: a master project (shell project) that contains all the content (the entire project) for package delivery or package testing.
  2. Base component: Performs functions independently of any other component. Mainly include: * Functions that cannot be used with services (such as string or data encryption, category encapsulation) * Encapsulation of third-party libraries (such as AFNetworking, SDWebImage encapsulation)
  3. Business common components: Rely on infrastructure components or system components such as UIKit to create functions (such as sharing, payment, network access) common to businesses
  4. Intermediate components: Connect business common components and business components, and call each other between business components. (e.g., a Mediator component)
  5. Business components: Separate business functions that are independent of other business components.

The problem of granularity will be encountered. If the granularity is set too large, the coupling between components will be too large. If the granularity is set too small, a lot of components and intermediate components will be produced, and the management cost of components will be too large. (Specific problems need specific analysis)

Cocoapods component management

1. Create a POD Spec file

Spec File Description

Pod::Spec.new do |spec| 
  spec.name = 'Reachability' spec.version = '3.1.0'
  spec.license = { :type= >'BSD' } 
  spec.homepage = 'https://github.com/tonymillion/Reachability' 
  spec.authors = { 'Tony Million'= >'[email protected]' } 
  spec.summary = 'ARC and GCD Compatible Reachability Class for iOS and OS X.' 
  spec.source = { :git => 'https://github.com/tonymillion/Reachability.git', :tag => 'v3.1.0' } 
  spec.source_files = 'Reachability.{h,m}' 
  spec.framework = 'SystemConfiguration'
end
Copy the code

For details about how to write projects based on the content, learn about Cocoapods supported projects on Git by looking at the *.spec file in your project. (1). Adding resource files using S.resource_bundles (2). You need to add multiple files, use an array s.s ource_files = [‘ ThirdSdk/Classes / / *. * * {h, m} ‘, ‘ThirdSdk/Classes / * * / * * / *. {h, m}’]

2. LICENSE file and readme. md file

Documentation of licenses and instructions. Had better refer to official writing method, detect however otherwise.

3. Create an Example project

The key to an Example project is to use a direct reference to the Module file in the Podfile for component development. Easy to debug individual components such as pod ‘ThirdSdk’, :path => ‘.. / ‘

Create a local database (cocoapods image)

Create a new Git library named Specs to keep all the local private libraries. Add a private Cocoapods Specs image using pod repo add [name] [Git address]. Use pod repo push repo [name.podSpec] to push a private component to a private third-party library image.

5. Rely on third-party libraries

You can add dependent third-party libraries to your Podfile, including Cocoapods and private native libraries.

platform :ios, '7.0'

source 'git@code.*.com:ios/Specs.git'

source 'https://github.com/CocoaPods/Specs.git'

target 'ThirdSdk_Example' do
  pod 'ThirdSdk', :path => '.. / '
  
  #cocoapods specs
  pod 'AliyunOSSiOS'
  
  #local specs
  pod 'WebService'
end
Copy the code

Among them

  • (1)source 'git@code.*.com:ios/Specs.git'Is to request a reference to a locally specified data address.
  • (2)source 'https://github.com/CocoaPods/Specs.git'Is the official third-party library address of Cocoapods.
  • (3)pod 'AliyunOSSiOS'The reference is from Cocoapods’ third-party library.
  • (4)pod 'WebService'References are private third-party libraries.

Dependencies between components

(1) For the dependency of the base component, the adoption of Pod directly leads to the import header file in the code. This approach results in high coupling of the underlying components. The granularity of components can be set to be smaller, and independent components that do not depend on other components can be extracted as far as possible. These independent components are packaged into a larger component for easy management. Such as Podfile

#local specs
  pod 'Account'
  pod 'AppPod'
  pod 'WebService'
Copy the code

One of them, AppPod, is a collection that contains many independent base components.

(2) If it is a business component, the coupling between components must be avoided between different businesses. Mediator component should be adopted as middleware to reduce the coupling. For details, please refer to the introduction to iOS App Architecture (casatwy.com/iosying-yon…). Provide Demo preparation.

Iii. Main project

The main engineering (shell engineering) references all the components and implements the applied engineering.

IOS app Framework and Cocoapods content

  • Casatwy.com/iosying-yon…
  • www.cocoachina.com/ios/2016010…
  • Gracelancy.com/blog/2016/0…
  • Blog.csdn.net/xyxjn/artic…
  • Pingguohe.net/2015/11/24/…
  • Studentdeng. Making. IO/blog / 2013/0…
  • Ishalou.com/blog/2012/1…
  • Stackoverflow.com/questions/2…
  • www.cnblogs.com/Mr-ios/p/53…

supplement

1. Troubleshooting the pod install update failure

When using Cocoapods to manage code, if you update your code on GitHut and want to refresh the code by executing pod Install in project, you need to remove the Pods and Podfile.lock files and then execute Pod Install to refresh the code

Update the REPO using POD Update

Multiple pod installs will result in multiple Check Pods manifest.lock options in Build Phase, which can be removed.


Delete the cache files in the directory for third-party libraries to access/Users / * / Library/Caches/CocoaPods/Pods / *

Because it is possible that VERSION in the Pods directory holds a third-party library for that VERSION because the VERSION number is not increased, the cached files will be returned directly. So when private components have code changes, you can clear the directory under this folder, to carry out private component updates. 👍👍👍 (it took a long time to find the ultimate solution)


2. Generate folder form or create sub-components in Pod

In *.podspec files, create different sub-components based on functionality, as in AFN

s.subspec 'Security' do |ss|

ss.source_files = 'AFNetworking/AFSecurityPolicy.{h,m}'

ss.public_header_files = 'AFNetworking/AFSecurityPolicy.h'

ss.frameworks = 'Security'

end
Copy the code

Generated effect

This approach is also a subcomponent approach, and components of AFSecurityPolicy can be referenced directly in a POD, such as POD ‘AFNetworking/Security’, which only refers to the Security component, not the entire AFN component


During development, the folders are messy. When other components pod, the folders look like AFNetworking.


3. Podspec dependency usage

Components can rely on other third-party libraries, such as S. dependency ‘JTObjectMapping’AFNetworking. You can also rely on private third-party libraries: (1) Add a private Cocoapods Specs image using pod repo add [name] [Git address]. (2) Use pod repo push repo [name.podSpec] to push private components to private third-party library images. (3) In the component can be uploaded components can be used to rely on.

4. ThirdSdk components

You cannot include business or project-specific classes in the ThirdSdk component, which would lead to interdependencies. Including only third-party library code reduces coupling. If you have third-party libraries managed by Cocoapods, use Cocoapods instead.

5. Load static libraries and frameworks

ss.vendored_frameworks = 'ThirdSdk/AlipaySDK/AlipaySDK.framework'
ss.vendored_libraries = 'ThirdSdk/AlipaySDK/libcrypto.a'.'ThirdSdk/AlipaySDK/libssl.a'
Copy the code

The a file is not a source_files.

6. Runtime Cannot Return Bool Basic data type

return [target performSelector:action withObject:params];
Copy the code

If the value returned is a Bool or some other underlying data type, Crash will occur.

You need to set the return value to NSObject object type or nil.

7. When resources such as XIb and PNG are obtained from the component, the bundle is reset

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    NSString *bundlePath = [bundle pathForResource:@"StoreLocation" ofType:@"bundle"];
    if (bundlePath) {
        bundle = [NSBundle bundleWithPath:bundlePath];
    }
Copy the code

Where StoreLocation is consistent with the Settings of S.resource_bundles in podSpec.

s.resource_bundles = {
    'StoreLocation'= > ['StoreLocation/Assets/**/*'.'StoreLocation/Classes/Address/*.{xib}'']}Copy the code

8. Image and URL processing

1. Place the pictures used by each component in the Assets folder of the component. In iOS8 and later, a Xib accessing an image in a component is read from Assets in the component. However, in iOS7, Xib still reads files from Assets of [NSBundle mainBundle]. 2. Urls are not placed in a separate header file, but in the ViewModel of the component.

9. TAG refresh

When multiple people are collaborating and the TAG stays at 1.0.0, all tags need to be updated every time.

Grab and store all labels locally

10. Push component *.podspec file

pod repo push Specs AppPod.podspec --allow-warnings
Copy the code

Pod Cache clean –all can be used to clean the cache.

11. Set macros for different Configurations

When you add an ad-hoc configuration, you also need to set the DEBUG macro, and the DEBUG macro definition is used in the component, so you need to set the DEBUG for all components. Methods the following

Set the Debug parameter
post_install do |installer|

  installer.pods_project.targets.each do |target|

    target.build_configurations.each do |config|

      if config.name == 'Debug' 
       config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) DEBUG=1'
      
      end
      
      if config.name == 'Ad-hoc' 
       config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) DEBUG=1'
      
      end

end

end

end
Set parameters
Copy the code

12. Update OpenSSL failed

If the OpenSSL update fails, delete the/TMP/OpenSSL folder and try again.

13. Use of OpenSSL

#include < OpenSSL /e_os2.h> is used in the OpenSSL folder when using alipay SDK. When you put the SDK into a component, an error is reported indicating that the file cannot be found. Solution: Add ss.header_dir = “openssl” to the *. Podspec file to add the header folder OpenSSL.

14. ARC and MRC compatible

Put MAC users into subspecs

s.subspec 'JTObjectMapping' do |ss|
    ss.source_files = 'StoreBase/Classes/JTObjectMapping/*.{h,m}'
    ss.public_header_files = 'StoreBase/Classes/JTObjectMapping/*.h'

    ss.requires_arc = false
  end
Copy the code

Requires_arc = false because JTObjectMapping third-party library uses MRC. For ARC used in the main spec, declare ss.requires_arc = true. If the main spec is ARC and JTObjectMapping is MRC, a -fno-objc-ARC compilation macro will be added to all files in JTObjectMapping.

15. Version updates of base components

When the main project releases a version, the versions of the underlying components that depend on it are fixed and cannot be changed. When changes need to be made to the underlying component, the version needs to be updated, plus one. When the version number of an underlying component A changes, all components BCDS that depend on that component also change their versions. Then the COMPONENT EFG that depends on BCD also changes the version number, and so on

16. Release version modification

Release version modification: For base components, change all dependencies of base components to a larger version (for example, “=1.1.0” format). The version number must be specified. For example, if you have a component with a version number of 1.0.5, it has been developed from 1.0.1 to 1.0.5, and the 1.1.0 version needs to be modified before submission and executed. For the convenience of (1) online version can specify the specific version. (2) Facilitate the development of the next version. In the shell project, the pod file is modified to specify the dev branch of the business component and the version number must be specified.

Use of business components: At development time, code is fetched directly from the Dev branch in the Podfile and developed on dev. When you need to release a version for smoke testing, modify the podfile to specify the version number. Such as “= 1.1.0.

pod 'Location', :git => '[email protected]:ios/Location.git', :branch => 'dev'
Copy the code

Use of base components In each base component, use “~>1.0.3” for development, and add the version number each time you change it. If the base component depends on other components, change it to “~>1.0.3”, so that pod install can update to the latest version without cleaning the cache. When releasing a version, specify the version number in each component. Such as “= 1.1.0. Save the official version of each release, so that the version numbers of all components are clearly known. If the development is performed after the release of a version, you need to modify ~>1.1.0 after the release of a dependent version, which eliminates the need to clear the cache, facilitating development. During development, the version number is changed only for the version number to be changed. Other version numbers remain unchanged.

Image Resource Create an image resource pod and add images using S. resources. So in the XIB or imageNamed:””” directly accessible. Bundle control is not required. 👍 👍 👍

// END