David PHAM-VAN

Convert objective-c code to swift

@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 14
15 DART_SRC=$(shell find . -name '*.dart') 15 DART_SRC=$(shell find . -name '*.dart')
16 CLNG_SRC=$(shell find printing/ios -name '*.java' -o -name '*.m' -o -name '*.h') $(shell find printing/android -name '*.java' -o -name '*.m' -o -name '*.h') 16 CLNG_SRC=$(shell find printing/ios -name '*.java' -o -name '*.m' -o -name '*.h') $(shell find printing/android -name '*.java' -o -name '*.m' -o -name '*.h')
  17 + SWFT_SRC=$(shell find . -name '*.swift')
17 FONTS=pdf/open-sans.ttf pdf/roboto.ttf 18 FONTS=pdf/open-sans.ttf pdf/roboto.ttf
18 19
19 all: $(FONTS) format 20 all: $(FONTS) format
@@ -24,7 +25,7 @@ pdf/open-sans.ttf: @@ -24,7 +25,7 @@ pdf/open-sans.ttf:
24 pdf/roboto.ttf: 25 pdf/roboto.ttf:
25 curl -L "https://github.com/google/fonts/raw/master/apache/robotomono/RobotoMono-Regular.ttf" > $@ 26 curl -L "https://github.com/google/fonts/raw/master/apache/robotomono/RobotoMono-Regular.ttf" > $@
26 27
27 -format: format-dart format-clang 28 +format: format-dart format-clang format-swift
28 29
29 format-dart: $(DART_SRC) 30 format-dart: $(DART_SRC)
30 dartfmt -w --fix $^ 31 dartfmt -w --fix $^
@@ -32,6 +33,9 @@ format-dart: $(DART_SRC) @@ -32,6 +33,9 @@ format-dart: $(DART_SRC)
32 format-clang: $(CLNG_SRC) 33 format-clang: $(CLNG_SRC)
33 clang-format -style=Chromium -i $^ 34 clang-format -style=Chromium -i $^
34 35
  36 +format-swift: $(SWFT_SRC)
  37 + swiftformat --swiftversion 4.2 $^
  38 +
35 pdf/.dart_tool: 39 pdf/.dart_tool:
36 cd pdf ; pub get 40 cd pdf ; pub get
37 41
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 * Fix dart lint warnings 2 * Fix dart lint warnings
3 * Add documentation 3 * Add documentation
4 * Add a filename parameter for sharing 4 * Add a filename parameter for sharing
  5 +* Convert Objective-C code to Swift
5 6
6 # 1.3.3 7 # 1.3.3
7 * Update Readme 8 * Update Readme
@@ -8,7 +8,7 @@ buildscript { @@ -8,7 +8,7 @@ buildscript {
8 } 8 }
9 9
10 dependencies { 10 dependencies {
11 - classpath 'com.android.tools.build:gradle:3.1.2' 11 + classpath 'com.android.tools.build:gradle:3.2.1'
12 } 12 }
13 } 13 }
14 14
@@ -22,7 +22,7 @@ rootProject.allprojects { @@ -22,7 +22,7 @@ rootProject.allprojects {
22 apply plugin: 'com.android.library' 22 apply plugin: 'com.android.library'
23 23
24 android { 24 android {
25 - compileSdkVersion 26 25 + compileSdkVersion 28
26 26
27 defaultConfig { 27 defaultConfig {
28 minSdkVersion 19 28 minSdkVersion 19
@@ -11,14 +11,13 @@ @@ -11,14 +11,13 @@
11 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 11 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 12 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
13 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 13 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
14 - 669503AD9820A2FB8EB7D135 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 438EF44EBD2180BA9FEB6DD7 /* libPods-Runner.a */; }; 14 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
15 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 15 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
16 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
17 - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };  
18 - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };  
19 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 17 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
20 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 18 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
21 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 19 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
  20 + E8DE9257AFBCBC1504A2E8B5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E9F8451991F067F1B35AD2E /* Pods_Runner.framework */; };
22 /* End PBXBuildFile section */ 21 /* End PBXBuildFile section */
23 22
24 /* Begin PBXCopyFilesBuildPhase section */ 23 /* Begin PBXCopyFilesBuildPhase section */
@@ -39,17 +38,19 @@ @@ -39,17 +38,19 @@
39 /* Begin PBXFileReference section */ 38 /* Begin PBXFileReference section */
40 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 39 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
41 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 40 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
  41 + 1E8FFA8481E6F7C0861A5633 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
  42 + 36CCD35B2CCD6DA63F3BB856 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
42 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 43 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
43 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; }; 44 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
44 - 438EF44EBD2180BA9FEB6DD7 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 45 + 3E9F8451991F067F1B35AD2E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  46 + 64E6F026FD235CE443A8B399 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
  47 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
  48 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
45 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 49 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
46 - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };  
47 - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };  
48 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 50 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
49 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 51 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
50 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; }; 52 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
51 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
52 - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };  
53 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 54 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
54 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 55 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
55 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 56 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
@@ -63,18 +64,21 @@ @@ -63,18 +64,21 @@
63 files = ( 64 files = (
64 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 65 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
65 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 66 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
66 - 669503AD9820A2FB8EB7D135 /* libPods-Runner.a in Frameworks */, 67 + E8DE9257AFBCBC1504A2E8B5 /* Pods_Runner.framework in Frameworks */,
67 ); 68 );
68 runOnlyForDeploymentPostprocessing = 0; 69 runOnlyForDeploymentPostprocessing = 0;
69 }; 70 };
70 /* End PBXFrameworksBuildPhase section */ 71 /* End PBXFrameworksBuildPhase section */
71 72
72 /* Begin PBXGroup section */ 73 /* Begin PBXGroup section */
73 - 2BF041FD892A0BC85D754ACF /* Pods */ = { 74 + 55188E0E9477620B487B3E3D /* Pods */ = {
74 isa = PBXGroup; 75 isa = PBXGroup;
75 children = ( 76 children = (
  77 + 36CCD35B2CCD6DA63F3BB856 /* Pods-Runner.debug.xcconfig */,
  78 + 64E6F026FD235CE443A8B399 /* Pods-Runner.release.xcconfig */,
  79 + 1E8FFA8481E6F7C0861A5633 /* Pods-Runner.profile.xcconfig */,
76 ); 80 );
77 - name = Pods; 81 + path = Pods;
78 sourceTree = "<group>"; 82 sourceTree = "<group>";
79 }; 83 };
80 9740EEB11CF90186004384FC /* Flutter */ = { 84 9740EEB11CF90186004384FC /* Flutter */ = {
@@ -96,8 +100,8 @@ @@ -96,8 +100,8 @@
96 9740EEB11CF90186004384FC /* Flutter */, 100 9740EEB11CF90186004384FC /* Flutter */,
97 97C146F01CF9000F007C117D /* Runner */, 101 97C146F01CF9000F007C117D /* Runner */,
98 97C146EF1CF9000F007C117D /* Products */, 102 97C146EF1CF9000F007C117D /* Products */,
99 - 2BF041FD892A0BC85D754ACF /* Pods */,  
100 - A68417D4692CD8722C677E29 /* Frameworks */, 103 + 55188E0E9477620B487B3E3D /* Pods */,
  104 + A068841E0B33BBCDB05C8960 /* Frameworks */,
101 ); 105 );
102 sourceTree = "<group>"; 106 sourceTree = "<group>";
103 }; 107 };
@@ -112,8 +116,6 @@ @@ -112,8 +116,6 @@
112 97C146F01CF9000F007C117D /* Runner */ = { 116 97C146F01CF9000F007C117D /* Runner */ = {
113 isa = PBXGroup; 117 isa = PBXGroup;
114 children = ( 118 children = (
115 - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,  
116 - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,  
117 97C146FA1CF9000F007C117D /* Main.storyboard */, 119 97C146FA1CF9000F007C117D /* Main.storyboard */,
118 97C146FD1CF9000F007C117D /* Assets.xcassets */, 120 97C146FD1CF9000F007C117D /* Assets.xcassets */,
119 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 121 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@@ -121,6 +123,8 @@ @@ -121,6 +123,8 @@
121 97C146F11CF9000F007C117D /* Supporting Files */, 123 97C146F11CF9000F007C117D /* Supporting Files */,
122 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 124 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
123 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 125 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
  126 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
  127 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
124 ); 128 );
125 path = Runner; 129 path = Runner;
126 sourceTree = "<group>"; 130 sourceTree = "<group>";
@@ -128,15 +132,14 @@ @@ -128,15 +132,14 @@
128 97C146F11CF9000F007C117D /* Supporting Files */ = { 132 97C146F11CF9000F007C117D /* Supporting Files */ = {
129 isa = PBXGroup; 133 isa = PBXGroup;
130 children = ( 134 children = (
131 - 97C146F21CF9000F007C117D /* main.m */,  
132 ); 135 );
133 name = "Supporting Files"; 136 name = "Supporting Files";
134 sourceTree = "<group>"; 137 sourceTree = "<group>";
135 }; 138 };
136 - A68417D4692CD8722C677E29 /* Frameworks */ = { 139 + A068841E0B33BBCDB05C8960 /* Frameworks */ = {
137 isa = PBXGroup; 140 isa = PBXGroup;
138 children = ( 141 children = (
139 - 438EF44EBD2180BA9FEB6DD7 /* libPods-Runner.a */, 142 + 3E9F8451991F067F1B35AD2E /* Pods_Runner.framework */,
140 ); 143 );
141 name = Frameworks; 144 name = Frameworks;
142 sourceTree = "<group>"; 145 sourceTree = "<group>";
@@ -148,14 +151,14 @@ @@ -148,14 +151,14 @@
148 isa = PBXNativeTarget; 151 isa = PBXNativeTarget;
149 buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 152 buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
150 buildPhases = ( 153 buildPhases = (
151 - 4DD8C990B54E5CD60DA09BAD /* [CP] Check Pods Manifest.lock */, 154 + 1823E53487662DB3F45BAC31 /* [CP] Check Pods Manifest.lock */,
152 9740EEB61CF901F6004384FC /* Run Script */, 155 9740EEB61CF901F6004384FC /* Run Script */,
153 97C146EA1CF9000F007C117D /* Sources */, 156 97C146EA1CF9000F007C117D /* Sources */,
154 97C146EB1CF9000F007C117D /* Frameworks */, 157 97C146EB1CF9000F007C117D /* Frameworks */,
155 97C146EC1CF9000F007C117D /* Resources */, 158 97C146EC1CF9000F007C117D /* Resources */,
156 9705A1C41CF9048500538489 /* Embed Frameworks */, 159 9705A1C41CF9048500538489 /* Embed Frameworks */,
157 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 160 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
158 - 770C3FAAF999833574938C52 /* [CP] Embed Pods Frameworks */, 161 + 27917B59DB58561F8D7C1998 /* [CP] Embed Pods Frameworks */,
159 ); 162 );
160 buildRules = ( 163 buildRules = (
161 ); 164 );
@@ -177,6 +180,7 @@ @@ -177,6 +180,7 @@
177 TargetAttributes = { 180 TargetAttributes = {
178 97C146ED1CF9000F007C117D = { 181 97C146ED1CF9000F007C117D = {
179 CreatedOnToolsVersion = 7.3.1; 182 CreatedOnToolsVersion = 7.3.1;
  183 + LastSwiftMigration = 1010;
180 }; 184 };
181 }; 185 };
182 }; 186 };
@@ -213,21 +217,7 @@ @@ -213,21 +217,7 @@
213 /* End PBXResourcesBuildPhase section */ 217 /* End PBXResourcesBuildPhase section */
214 218
215 /* Begin PBXShellScriptBuildPhase section */ 219 /* Begin PBXShellScriptBuildPhase section */
216 - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {  
217 - isa = PBXShellScriptBuildPhase;  
218 - buildActionMask = 2147483647;  
219 - files = (  
220 - );  
221 - inputPaths = (  
222 - );  
223 - name = "Thin Binary";  
224 - outputPaths = (  
225 - );  
226 - runOnlyForDeploymentPostprocessing = 0;  
227 - shellPath = /bin/sh;  
228 - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";  
229 - };  
230 - 4DD8C990B54E5CD60DA09BAD /* [CP] Check Pods Manifest.lock */ = { 220 + 1823E53487662DB3F45BAC31 /* [CP] Check Pods Manifest.lock */ = {
231 isa = PBXShellScriptBuildPhase; 221 isa = PBXShellScriptBuildPhase;
232 buildActionMask = 2147483647; 222 buildActionMask = 2147483647;
233 files = ( 223 files = (
@@ -249,7 +239,7 @@ @@ -249,7 +239,7 @@
249 shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 239 shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
250 showEnvVarsInLog = 0; 240 showEnvVarsInLog = 0;
251 }; 241 };
252 - 770C3FAAF999833574938C52 /* [CP] Embed Pods Frameworks */ = { 242 + 27917B59DB58561F8D7C1998 /* [CP] Embed Pods Frameworks */ = {
253 isa = PBXShellScriptBuildPhase; 243 isa = PBXShellScriptBuildPhase;
254 buildActionMask = 2147483647; 244 buildActionMask = 2147483647;
255 files = ( 245 files = (
@@ -257,20 +247,36 @@ @@ -257,20 +247,36 @@
257 inputFileListPaths = ( 247 inputFileListPaths = (
258 ); 248 );
259 inputPaths = ( 249 inputPaths = (
260 - "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 250 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
261 "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", 251 "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
  252 + "${BUILT_PRODUCTS_DIR}/printing/printing.framework",
262 ); 253 );
263 name = "[CP] Embed Pods Frameworks"; 254 name = "[CP] Embed Pods Frameworks";
264 outputFileListPaths = ( 255 outputFileListPaths = (
265 ); 256 );
266 outputPaths = ( 257 outputPaths = (
267 "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", 258 "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
  259 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/printing.framework",
268 ); 260 );
269 runOnlyForDeploymentPostprocessing = 0; 261 runOnlyForDeploymentPostprocessing = 0;
270 shellPath = /bin/sh; 262 shellPath = /bin/sh;
271 - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 263 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
272 showEnvVarsInLog = 0; 264 showEnvVarsInLog = 0;
273 }; 265 };
  266 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
  267 + isa = PBXShellScriptBuildPhase;
  268 + buildActionMask = 2147483647;
  269 + files = (
  270 + );
  271 + inputPaths = (
  272 + );
  273 + name = "Thin Binary";
  274 + outputPaths = (
  275 + );
  276 + runOnlyForDeploymentPostprocessing = 0;
  277 + shellPath = /bin/sh;
  278 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
  279 + };
274 9740EEB61CF901F6004384FC /* Run Script */ = { 280 9740EEB61CF901F6004384FC /* Run Script */ = {
275 isa = PBXShellScriptBuildPhase; 281 isa = PBXShellScriptBuildPhase;
276 buildActionMask = 2147483647; 282 buildActionMask = 2147483647;
@@ -292,8 +298,7 @@ @@ -292,8 +298,7 @@
292 isa = PBXSourcesBuildPhase; 298 isa = PBXSourcesBuildPhase;
293 buildActionMask = 2147483647; 299 buildActionMask = 2147483647;
294 files = ( 300 files = (
295 - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,  
296 - 97C146F31CF9000F007C117D /* main.m in Sources */, 301 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
297 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 302 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
298 ); 303 );
299 runOnlyForDeploymentPostprocessing = 0; 304 runOnlyForDeploymentPostprocessing = 0;
@@ -388,8 +393,9 @@ @@ -388,8 +393,9 @@
388 "$(inherited)", 393 "$(inherited)",
389 "$(PROJECT_DIR)/Flutter", 394 "$(PROJECT_DIR)/Flutter",
390 ); 395 );
391 - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 396 + PRODUCT_BUNDLE_IDENTIFIER = net.nfet.flutter.printingExample;
392 PRODUCT_NAME = "$(TARGET_NAME)"; 397 PRODUCT_NAME = "$(TARGET_NAME)";
  398 + SWIFT_VERSION = 4.2;
393 VERSIONING_SYSTEM = "apple-generic"; 399 VERSIONING_SYSTEM = "apple-generic";
394 }; 400 };
395 name = Profile; 401 name = Profile;
@@ -495,6 +501,7 @@ @@ -495,6 +501,7 @@
495 IPHONEOS_DEPLOYMENT_TARGET = 8.0; 501 IPHONEOS_DEPLOYMENT_TARGET = 8.0;
496 MTL_ENABLE_DEBUG_INFO = NO; 502 MTL_ENABLE_DEBUG_INFO = NO;
497 SDKROOT = iphoneos; 503 SDKROOT = iphoneos;
  504 + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
498 TARGETED_DEVICE_FAMILY = "1,2"; 505 TARGETED_DEVICE_FAMILY = "1,2";
499 VALIDATE_PRODUCT = YES; 506 VALIDATE_PRODUCT = YES;
500 }; 507 };
@@ -505,6 +512,7 @@ @@ -505,6 +512,7 @@
505 baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 512 baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
506 buildSettings = { 513 buildSettings = {
507 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 514 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  515 + CLANG_ENABLE_MODULES = YES;
508 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 516 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
509 ENABLE_BITCODE = NO; 517 ENABLE_BITCODE = NO;
510 FRAMEWORK_SEARCH_PATHS = ( 518 FRAMEWORK_SEARCH_PATHS = (
@@ -517,8 +525,11 @@ @@ -517,8 +525,11 @@
517 "$(inherited)", 525 "$(inherited)",
518 "$(PROJECT_DIR)/Flutter", 526 "$(PROJECT_DIR)/Flutter",
519 ); 527 );
520 - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 528 + PRODUCT_BUNDLE_IDENTIFIER = net.nfet.flutter.printingExample;
521 PRODUCT_NAME = "$(TARGET_NAME)"; 529 PRODUCT_NAME = "$(TARGET_NAME)";
  530 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  531 + SWIFT_OPTIMIZATION_LEVEL = "-Onone";
  532 + SWIFT_VERSION = 4.2;
522 VERSIONING_SYSTEM = "apple-generic"; 533 VERSIONING_SYSTEM = "apple-generic";
523 }; 534 };
524 name = Debug; 535 name = Debug;
@@ -528,6 +539,7 @@ @@ -528,6 +539,7 @@
528 baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 539 baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
529 buildSettings = { 540 buildSettings = {
530 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 541 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  542 + CLANG_ENABLE_MODULES = YES;
531 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 543 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
532 ENABLE_BITCODE = NO; 544 ENABLE_BITCODE = NO;
533 FRAMEWORK_SEARCH_PATHS = ( 545 FRAMEWORK_SEARCH_PATHS = (
@@ -540,8 +552,10 @@ @@ -540,8 +552,10 @@
540 "$(inherited)", 552 "$(inherited)",
541 "$(PROJECT_DIR)/Flutter", 553 "$(PROJECT_DIR)/Flutter",
542 ); 554 );
543 - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 555 + PRODUCT_BUNDLE_IDENTIFIER = net.nfet.flutter.printingExample;
544 PRODUCT_NAME = "$(TARGET_NAME)"; 556 PRODUCT_NAME = "$(TARGET_NAME)";
  557 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  558 + SWIFT_VERSION = 4.2;
545 VERSIONING_SYSTEM = "apple-generic"; 559 VERSIONING_SYSTEM = "apple-generic";
546 }; 560 };
547 name = Release; 561 name = Release;
1 -#import <Flutter/Flutter.h>  
2 -#import <UIKit/UIKit.h>  
3 -  
4 -@interface AppDelegate : FlutterAppDelegate  
5 -  
6 -@end  
1 -#include "AppDelegate.h"  
2 -#include "GeneratedPluginRegistrant.h"  
3 -  
4 -@implementation AppDelegate  
5 -  
6 -- (BOOL)application:(UIApplication *)application  
7 - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
8 - [GeneratedPluginRegistrant registerWithRegistry:self];  
9 - // Override point for customization after application launch.  
10 - return [super application:application didFinishLaunchingWithOptions:launchOptions];  
11 -}  
12 -  
13 -@end  
  1 +import Flutter
  2 +import UIKit
  3 +
  4 +@UIApplicationMain
  5 +@objc class AppDelegate: FlutterAppDelegate {
  6 + override func application(
  7 + _ application: UIApplication,
  8 + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  9 + ) -> Bool {
  10 + GeneratedPluginRegistrant.register(with: self)
  11 + return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  12 + }
  13 +}
  1 +#import "GeneratedPluginRegistrant.h"
1 -#import <Flutter/Flutter.h>  
2 -#import <UIKit/UIKit.h>  
3 -#import "AppDelegate.h"  
4 -  
5 -int main(int argc, char* argv[]) {  
6 - @autoreleasepool {  
7 - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));  
8 - }  
9 -}  
1 -/*  
2 - * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>  
3 - *  
4 - * Licensed under the Apache License, Version 2.0 (the "License");  
5 - * you may not use this file except in compliance with the License.  
6 - * You may obtain a copy of the License at  
7 - *  
8 - * http://www.apache.org/licenses/LICENSE-2.0  
9 - *  
10 - * Unless required by applicable law or agreed to in writing, software  
11 - * distributed under the License is distributed on an "AS IS" BASIS,  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
13 - * See the License for the specific language governing permissions and  
14 - * limitations under the License.  
15 - */  
16 -  
17 -#import <Flutter/Flutter.h>  
18 -  
19 -@interface PdfPrintPageRenderer : UIPrintPageRenderer  
20 -  
21 -- (instancetype)init:(FlutterMethodChannel*)channel;  
22 -- (void)drawPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)printableRect;  
23 -- (void)setDocument:(NSData*)data;  
24 -  
25 -@property(nonatomic, readonly) NSInteger numberOfPages;  
26 -@end  
1 -/*  
2 - * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>  
3 - *  
4 - * Licensed under the Apache License, Version 2.0 (the "License");  
5 - * you may not use this file except in compliance with the License.  
6 - * You may obtain a copy of the License at  
7 - *  
8 - * http://www.apache.org/licenses/LICENSE-2.0  
9 - *  
10 - * Unless required by applicable law or agreed to in writing, software  
11 - * distributed under the License is distributed on an "AS IS" BASIS,  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
13 - * See the License for the specific language governing permissions and  
14 - * limitations under the License.  
15 - */  
16 -  
17 -#import "PageRenderer.h"  
18 -  
19 -@implementation PdfPrintPageRenderer {  
20 - FlutterMethodChannel* channel;  
21 - CGPDFDocumentRef pdfDocument;  
22 - NSLock* lock;  
23 -}  
24 -  
25 -- (instancetype)init:(FlutterMethodChannel*)channel {  
26 - self = [super init];  
27 - self->channel = channel;  
28 - self->lock = [[NSLock alloc] init];  
29 - self->pdfDocument = nil;  
30 - return self;  
31 -}  
32 -  
33 -- (void)dealloc {  
34 - if (self->pdfDocument != nil) {  
35 - CGPDFDocumentRelease(self->pdfDocument);  
36 - }  
37 -}  
38 -  
39 -- (NSInteger)numberOfPages {  
40 - NSNumber* width = [[NSNumber alloc] initWithDouble:self.paperRect.size.width];  
41 - NSNumber* height =  
42 - [[NSNumber alloc] initWithDouble:self.paperRect.size.height];  
43 - NSNumber* marginLeft =  
44 - [[NSNumber alloc] initWithDouble:self.printableRect.origin.x];  
45 - NSNumber* marginTop =  
46 - [[NSNumber alloc] initWithDouble:self.printableRect.origin.y];  
47 - NSNumber* marginRight =  
48 - [[NSNumber alloc] initWithDouble:self.paperRect.size.width -  
49 - (self.printableRect.origin.x +  
50 - self.printableRect.size.width)];  
51 - NSNumber* marginBottom =  
52 - [[NSNumber alloc] initWithDouble:self.paperRect.size.height -  
53 - (self.printableRect.origin.y +  
54 - self.printableRect.size.height)];  
55 -  
56 - NSDictionary* arg = @{  
57 - @"width" : width,  
58 - @"height" : height,  
59 - @"marginLeft" : marginLeft,  
60 - @"marginTop" : marginTop,  
61 - @"marginRight" : marginRight,  
62 - @"marginBottom" : marginBottom,  
63 - };  
64 -  
65 - [lock lock];  
66 - [channel invokeMethod:@"onLayout" arguments:arg];  
67 - [lock lock];  
68 - [lock unlock];  
69 -  
70 - size_t pages = CGPDFDocumentGetNumberOfPages(pdfDocument);  
71 -  
72 - return pages;  
73 -}  
74 -  
75 -- (void)drawPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)printableRect {  
76 - CGContextRef ctx = UIGraphicsGetCurrentContext();  
77 - CGPDFPageRef page = CGPDFDocumentGetPage(pdfDocument, pageIndex + 1);  
78 - CGContextScaleCTM(ctx, 1.0, -1.0);  
79 - CGContextTranslateCTM(ctx, 0.0, -self.paperRect.size.height);  
80 - CGContextDrawPDFPage(ctx, page);  
81 -}  
82 -  
83 -void dataProviderReleaseDataCallback(void* info,  
84 - const void* data,  
85 - size_t size) {  
86 - free((void*)data);  
87 -}  
88 -  
89 -- (void)setDocument:(NSData*)data {  
90 - void* buffer = malloc(data.length);  
91 - memcpy(buffer, data.bytes, data.length);  
92 - CGDataProviderRef dataProvider = CGDataProviderCreateWithData(  
93 - NULL, buffer, data.length, dataProviderReleaseDataCallback);  
94 - if (pdfDocument != nil) {  
95 - CGPDFDocumentRelease(pdfDocument);  
96 - pdfDocument = nil;  
97 - }  
98 - pdfDocument = CGPDFDocumentCreateWithProvider(dataProvider);  
99 - CGDataProviderRelease(dataProvider);  
100 - [lock unlock];  
101 -}  
102 -  
103 -@end  
  1 +/*
  2 + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +import Flutter
  18 +
  19 +func dataProviderReleaseDataCallback(info _: UnsafeMutableRawPointer?, data: UnsafeRawPointer, size _: Int) {
  20 + data.deallocate()
  21 +}
  22 +
  23 +class PdfPrintPageRenderer: UIPrintPageRenderer {
  24 + private var channel: FlutterMethodChannel?
  25 + private var pdfDocument: CGPDFDocument?
  26 + private var lock: NSLock?
  27 +
  28 + init(_ channel: FlutterMethodChannel?) {
  29 + super.init()
  30 + self.channel = channel
  31 + lock = NSLock()
  32 + pdfDocument = nil
  33 + }
  34 +
  35 + override func drawPage(at pageIndex: Int, in _: CGRect) {
  36 + let ctx = UIGraphicsGetCurrentContext()
  37 + let page = pdfDocument?.page(at: pageIndex + 1)
  38 + ctx?.scaleBy(x: 1.0, y: -1.0)
  39 + ctx?.translateBy(x: 0.0, y: -paperRect.size.height)
  40 + ctx?.drawPDFPage(page!)
  41 + }
  42 +
  43 + func setDocument(_ data: Data?) {
  44 + let bytesPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: data?.count ?? 0)
  45 + data?.copyBytes(to: bytesPointer, count: data?.count ?? 0)
  46 + let dataProvider = CGDataProvider(dataInfo: nil, data: bytesPointer, size: data?.count ?? 0, releaseData: dataProviderReleaseDataCallback)
  47 + pdfDocument = CGPDFDocument(dataProvider!)
  48 + lock?.unlock()
  49 + }
  50 +
  51 + override var numberOfPages: Int {
  52 + let width = NSNumber(value: Double(paperRect.size.width))
  53 + let height = NSNumber(value: Double(paperRect.size.height))
  54 + let marginLeft = NSNumber(value: Double(printableRect.origin.x))
  55 + let marginTop = NSNumber(value: Double(printableRect.origin.y))
  56 + let marginRight = NSNumber(value: Double(paperRect.size.width - (printableRect.origin.x + printableRect.size.width)))
  57 + let marginBottom = NSNumber(value: Double(paperRect.size.height - (printableRect.origin.y + printableRect.size.height)))
  58 +
  59 + let arg = [
  60 + "width": width,
  61 + "height": height,
  62 + "marginLeft": marginLeft,
  63 + "marginTop": marginTop,
  64 + "marginRight": marginRight,
  65 + "marginBottom": marginBottom,
  66 + ]
  67 +
  68 + lock?.lock()
  69 + channel?.invokeMethod("onLayout", arguments: arg)
  70 + lock?.lock()
  71 + lock?.unlock()
  72 +
  73 + let pages = pdfDocument?.numberOfPages ?? 0
  74 +
  75 + return pages
  76 + }
  77 +}
@@ -16,8 +16,5 @@ @@ -16,8 +16,5 @@
16 16
17 #import <Flutter/Flutter.h> 17 #import <Flutter/Flutter.h>
18 18
19 -@interface PrintingPlugin  
20 - : NSObject <FlutterPlugin, UIPrintInteractionControllerDelegate>  
21 -  
22 -- (instancetype)init:(FlutterMethodChannel*)channel; 19 +@interface PrintingPlugin : NSObject <FlutterPlugin>
23 @end 20 @end
@@ -15,133 +15,10 @@ @@ -15,133 +15,10 @@
15 */ 15 */
16 16
17 #import "PrintingPlugin.h" 17 #import "PrintingPlugin.h"
18 -#import "PageRenderer.h"  
19 -  
20 -@implementation PrintingPlugin {  
21 - FlutterMethodChannel* channel;  
22 - PdfPrintPageRenderer* renderer;  
23 -} 18 +#import <printing/printing-Swift.h>
24 19
  20 +@implementation PrintingPlugin
25 + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { 21 + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
26 - FlutterMethodChannel* channel =  
27 - [FlutterMethodChannel methodChannelWithName:@"printing"  
28 - binaryMessenger:[registrar messenger]];  
29 - PrintingPlugin* instance = [[PrintingPlugin alloc] init:channel];  
30 - [registrar addMethodCallDelegate:instance channel:channel];  
31 -}  
32 -  
33 -- (instancetype)init:(FlutterMethodChannel*)channel {  
34 - self = [super init];  
35 - self->channel = channel;  
36 - self->renderer = nil;  
37 - return self;  
38 -}  
39 -  
40 -- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {  
41 - if ([@"printPdf" isEqualToString:call.method]) {  
42 - [self printPdf:[call.arguments objectForKey:@"name"]];  
43 - result(@1);  
44 - } else if ([@"writePdf" isEqualToString:call.method]) {  
45 - [self writePdf:[call.arguments objectForKey:@"doc"]];  
46 - result(@1);  
47 - } else if ([@"sharePdf" isEqualToString:call.method]) {  
48 - [self sharePdf:[call.arguments objectForKey:@"doc"]  
49 - withSourceRect:CGRectMake(  
50 - [[call.arguments objectForKey:@"x"] floatValue],  
51 - [[call.arguments objectForKey:@"y"] floatValue],  
52 - [[call.arguments objectForKey:@"w"] floatValue],  
53 - [[call.arguments objectForKey:@"h"] floatValue])  
54 - andName:[call.arguments objectForKey:@"name"]];  
55 - result(@1);  
56 - } else {  
57 - result(FlutterMethodNotImplemented);  
58 - } 22 + [SwiftPrintingPlugin registerWithRegistrar:registrar];
59 } 23 }
60 -  
61 -- (void)printPdf:(nonnull NSString*)name {  
62 - BOOL printing = [UIPrintInteractionController isPrintingAvailable];  
63 - if (!printing) {  
64 - NSLog(@"printing not available");  
65 - return;  
66 - }  
67 -  
68 - UIPrintInteractionController* controller =  
69 - [UIPrintInteractionController sharedPrintController];  
70 - [controller setDelegate:self];  
71 -  
72 - UIPrintInfo* printInfo = [UIPrintInfo printInfo];  
73 - printInfo.jobName = name;  
74 - printInfo.outputType = UIPrintInfoOutputGeneral;  
75 - controller.printInfo = printInfo;  
76 - renderer = [[PdfPrintPageRenderer alloc] init:channel];  
77 - [controller setPrintPageRenderer:renderer];  
78 - UIPrintInteractionCompletionHandler completionHandler =  
79 - ^(UIPrintInteractionController* printController, BOOL completed,  
80 - NSError* error) {  
81 - if (!completed && error) {  
82 - NSLog(@"FAILED! due to error in domain %@ with error code %u",  
83 - error.domain, (unsigned int)error.code);  
84 - }  
85 - self->renderer = nil;  
86 - };  
87 -  
88 - [controller presentAnimated:YES completionHandler:completionHandler];  
89 -}  
90 -  
91 -- (void)writePdf:(nonnull FlutterStandardTypedData*)data {  
92 - [renderer setDocument:data.data];  
93 -}  
94 -  
95 -- (void)sharePdf:(nonnull FlutterStandardTypedData*)data  
96 - withSourceRect:(CGRect)rect  
97 - andName:(NSString*)name {  
98 - NSURL* tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()  
99 - isDirectory:YES];  
100 -  
101 - CFUUIDRef uuid = CFUUIDCreate(NULL);  
102 - assert(uuid != nil);  
103 -  
104 - CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);  
105 - assert(uuidStr != nil);  
106 -  
107 - NSURL* fileURL;  
108 - if ([name isEqual:[NSNull null]]) {  
109 - fileURL = [[tmpDirURL  
110 - URLByAppendingPathComponent:[NSString stringWithFormat:@"document-%@",  
111 - uuidStr]]  
112 - URLByAppendingPathExtension:@"pdf"];  
113 - } else {  
114 - fileURL = [tmpDirURL URLByAppendingPathComponent:name];  
115 - }  
116 - assert(fileURL != nil);  
117 -  
118 - CFRelease(uuidStr);  
119 - CFRelease(uuid);  
120 -  
121 - NSString* path = [fileURL path];  
122 -  
123 - NSError* error;  
124 - if (![[data data] writeToFile:path  
125 - options:NSDataWritingAtomic  
126 - error:&error]) {  
127 - NSLog(@"sharePdf error: %@", [error localizedDescription]);  
128 - return;  
129 - }  
130 -  
131 - UIActivityViewController* activityViewController =  
132 - [[UIActivityViewController alloc] initWithActivityItems:@[ fileURL ]  
133 - applicationActivities:nil];  
134 - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {  
135 - UIViewController* controller =  
136 - [UIApplication sharedApplication].keyWindow.rootViewController;  
137 - activityViewController.popoverPresentationController.sourceView =  
138 - controller.view;  
139 - activityViewController.popoverPresentationController.sourceRect = rect;  
140 - }  
141 - [[UIApplication sharedApplication].keyWindow.rootViewController  
142 - presentViewController:activityViewController  
143 - animated:YES  
144 - completion:nil];  
145 -}  
146 -  
147 @end 24 @end
  1 +/*
  2 + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +import Flutter
  18 +import UIKit
  19 +
  20 +public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionControllerDelegate {
  21 + private var channel: FlutterMethodChannel?
  22 + private var renderer: PdfPrintPageRenderer?
  23 +
  24 + init(_ channel: FlutterMethodChannel?) {
  25 + super.init()
  26 + self.channel = channel
  27 + renderer = nil
  28 + }
  29 +
  30 + public static func register(with registrar: FlutterPluginRegistrar) {
  31 + let channel = FlutterMethodChannel(name: "printing", binaryMessenger: registrar.messenger())
  32 + let instance = SwiftPrintingPlugin(channel)
  33 + registrar.addMethodCallDelegate(instance, channel: channel)
  34 + }
  35 +
  36 + public func handle(_ call: FlutterMethodCall, result: FlutterResult) {
  37 + let args = call.arguments! as! [String: Any]
  38 + if "printPdf" == call.method {
  39 + printPdf(args["name"] as? String ?? "")
  40 + result(NSNumber(value: 1))
  41 + } else if "writePdf" == call.method {
  42 + if let object = args["doc"] as? FlutterStandardTypedData {
  43 + writePdf(object)
  44 + }
  45 + result(NSNumber(value: 1))
  46 + } else if "sharePdf" == call.method {
  47 + if let object = args["doc"] as? FlutterStandardTypedData {
  48 + sharePdf(
  49 + object,
  50 + withSourceRect: CGRect(x: CGFloat((args["x"] as? NSNumber)?.floatValue ?? 0.0), y: CGFloat((args["y"] as? NSNumber)?.floatValue ?? 0.0), width: CGFloat((args["w"] as? NSNumber)?.floatValue ?? 0.0), height: CGFloat((args["h"] as? NSNumber)?.floatValue ?? 0.0)),
  51 + andName: args["name"] as? String
  52 + )
  53 + }
  54 + result(NSNumber(value: 1))
  55 + } else {
  56 + result(FlutterMethodNotImplemented)
  57 + }
  58 + }
  59 +
  60 + func completionHandler(printController _: UIPrintInteractionController, completed: Bool, error: Error?) {
  61 + if !completed, error != nil {
  62 + print("Unable to print: \(error?.localizedDescription ?? "unknown error")")
  63 + }
  64 + renderer = nil
  65 + }
  66 +
  67 + func printPdf(_ name: String) {
  68 + let printing = UIPrintInteractionController.isPrintingAvailable
  69 + if !printing {
  70 + print("printing not available")
  71 + return
  72 + }
  73 +
  74 + let controller = UIPrintInteractionController.shared
  75 + controller.delegate = self
  76 +
  77 + let printInfo = UIPrintInfo.printInfo()
  78 + printInfo.jobName = name
  79 + printInfo.outputType = .general
  80 + controller.printInfo = printInfo
  81 + renderer = PdfPrintPageRenderer(channel)
  82 + controller.printPageRenderer = renderer
  83 + controller.present(animated: true, completionHandler: completionHandler)
  84 + }
  85 +
  86 + func writePdf(_ data: FlutterStandardTypedData) {
  87 + renderer?.setDocument(data.data)
  88 + }
  89 +
  90 + func sharePdf(_ data: FlutterStandardTypedData, withSourceRect rect: CGRect, andName name: String?) {
  91 + let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
  92 +
  93 + let uuid = CFUUIDCreate(nil)
  94 + assert(uuid != nil)
  95 +
  96 + let uuidStr = CFUUIDCreateString(nil, uuid)
  97 + assert(uuidStr != nil)
  98 +
  99 + var fileURL: URL
  100 + if name == nil {
  101 + fileURL = tmpDirURL.appendingPathComponent("document-\(uuidStr ?? "1" as CFString)").appendingPathExtension("pdf")
  102 + } else {
  103 + fileURL = tmpDirURL.appendingPathComponent(name!)
  104 + }
  105 +
  106 + do {
  107 + try data.data.write(to: fileURL, options: .atomic)
  108 + } catch {
  109 + print("sharePdf error: \(error.localizedDescription)")
  110 + return
  111 + }
  112 +
  113 + let activityViewController = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)
  114 + if UI_USER_INTERFACE_IDIOM() == .pad {
  115 + let controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController
  116 + activityViewController.popoverPresentationController?.sourceView = controller?.view
  117 + activityViewController.popoverPresentationController?.sourceRect = rect
  118 + }
  119 + UIApplication.shared.keyWindow?.rootViewController?.present(activityViewController, animated: true)
  120 + }
  121 +}
@@ -12,6 +12,10 @@ dependencies: @@ -12,6 +12,10 @@ dependencies:
12 sdk: flutter 12 sdk: flutter
13 pdf: "^1.3.0" 13 pdf: "^1.3.0"
14 14
  15 +dev_dependencies:
  16 + flutter_test:
  17 + sdk: flutter
  18 +
15 flutter: 19 flutter:
16 plugin: 20 plugin:
17 androidPackage: net.nfet.flutter.printing 21 androidPackage: net.nfet.flutter.printing