Skip to content

Commit 71581f0

Browse files
committed
Add client for Ulysses app #13
1 parent 9322279 commit 71581f0

File tree

8 files changed

+202
-24
lines changed

8 files changed

+202
-24
lines changed

CallbackURLKit.podspec

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ Pod::Spec.new do |s|
3333
sp.dependency 'CallbackURLKit/Core'
3434
end
3535

36+
s.subspec "Ulysses" do |sp|
37+
sp.source_files = "Clients/Ulysses.swift"
38+
sp.dependency 'CallbackURLKit/Core'
39+
end
40+
3641
end

CallbackURLKit.xcodeproj/project.pbxproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
48D0A14A1F0E28CE0019B815 /* Ulysses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A1491F0E28CE0019B815 /* Ulysses.swift */; };
11+
48D0A14B1F0E298B0019B815 /* CallbackURLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C4A8D5101C37D84A00DB3306 /* CallbackURLKit.framework */; };
1012
C418B1DD1C386C160097FDD9 /* CallbackURLKitOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = C418B1DC1C386C160097FDD9 /* CallbackURLKitOSX.h */; settings = {ATTRIBUTES = (Public, ); }; };
1113
C4A8D5141C37D84A00DB3306 /* CallbackURLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C4A8D5131C37D84A00DB3306 /* CallbackURLKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
1214
C4DB1E311D8421DE008DD3FB /* CallbackURLKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DB1E2C1D8421DE008DD3FB /* CallbackURLKit.swift */; };
@@ -24,6 +26,7 @@
2426
/* End PBXBuildFile section */
2527

2628
/* Begin PBXFileReference section */
29+
48D0A1491F0E28CE0019B815 /* Ulysses.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Ulysses.swift; path = Clients/Ulysses.swift; sourceTree = "<group>"; };
2730
C418B1DA1C386C160097FDD9 /* CallbackURLKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CallbackURLKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2831
C418B1DC1C386C160097FDD9 /* CallbackURLKitOSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CallbackURLKitOSX.h; sourceTree = "<group>"; };
2932
C418B1DE1C386C160097FDD9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -60,6 +63,7 @@
6063
isa = PBXFrameworksBuildPhase;
6164
buildActionMask = 2147483647;
6265
files = (
66+
48D0A14B1F0E298B0019B815 /* CallbackURLKit.framework in Frameworks */,
6367
);
6468
runOnlyForDeploymentPostprocessing = 0;
6569
};
@@ -122,6 +126,7 @@
122126
isa = PBXGroup;
123127
children = (
124128
C4E32D4F1C398AAC005CD033 /* GoogleChrome.swift */,
129+
48D0A1491F0E28CE0019B815 /* Ulysses.swift */,
125130
);
126131
name = Clients;
127132
sourceTree = "<group>";
@@ -313,6 +318,7 @@
313318
buildActionMask = 2147483647;
314319
files = (
315320
C4E32D5E1C398AE5005CD033 /* GoogleChrome.swift in Sources */,
321+
48D0A14A1F0E28CE0019B815 /* Ulysses.swift in Sources */,
316322
);
317323
runOnlyForDeploymentPostprocessing = 0;
318324
};
@@ -469,6 +475,7 @@
469475
INFOPLIST_FILE = CallbackURLKit/Info.plist;
470476
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
471477
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
478+
OTHER_SWIFT_FLAGS = "";
472479
PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.CallbackURLKit;
473480
PRODUCT_NAME = "$(TARGET_NAME)";
474481
SKIP_INSTALL = YES;
@@ -489,6 +496,7 @@
489496
INFOPLIST_FILE = CallbackURLKit/Info.plist;
490497
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
491498
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
499+
OTHER_SWIFT_FLAGS = "";
492500
PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.CallbackURLKit;
493501
PRODUCT_NAME = "$(TARGET_NAME)";
494502
SKIP_INSTALL = YES;
@@ -507,6 +515,7 @@
507515
INFOPLIST_FILE = CallbackURLKitClients/Info.plist;
508516
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
509517
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
518+
OTHER_SWIFT_FLAGS = "-DIMPORT";
510519
PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.CallbackURLKitClients;
511520
PRODUCT_NAME = "$(TARGET_NAME)";
512521
SKIP_INSTALL = YES;
@@ -525,6 +534,7 @@
525534
INFOPLIST_FILE = CallbackURLKitClients/Info.plist;
526535
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
527536
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
537+
OTHER_SWIFT_FLAGS = "-DIMPORT";
528538
PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.CallbackURLKitClients;
529539
PRODUCT_NAME = "$(TARGET_NAME)";
530540
SKIP_INSTALL = YES;

Clients/GoogleChrome.swift

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,53 @@
22
// GoogleChrome
33
// CallbackURLKit
44
/*
5-
The MIT License (MIT)
6-
Copyright (c) 2016 Eric Marchand (phimage)
7-
Permission is hereby granted, free of charge, to any person obtaining a copy
8-
of this software and associated documentation files (the "Software"), to deal
9-
in the Software without restriction, including without limitation the rights
10-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11-
copies of the Software, and to permit persons to whom the Software is
12-
furnished to do so, subject to the following conditions:
13-
The above copyright notice and this permission notice shall be included in all
14-
copies or substantial portions of the Software.
15-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
22-
*/
23-
// import CallbackURLKit
5+
The MIT License (MIT)
6+
Copyright (c) 2016 Eric Marchand (phimage)
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+
*/
23+
#if IMPORT
24+
import CallbackURLKit
25+
#endif
2426

27+
/*
28+
Google chrome client class
29+
https://developer.chrome.com/multidevice/ios/links
30+
*/
2531
public class GoogleChrome: Client {
32+
33+
#if os(macOS)
34+
public static let DownloadURL = URL(string: "https://www.google.com/chrome/browser/desktop/index.html")
35+
#else
36+
public static let DownloadURL = URL(string: "itms-apps://itunes.apple.com/us/app/chrome/id535886823")
37+
#endif
2638

2739
public init() {
2840
super.init(urlScheme: "googlechrome-x-callback")
2941
}
30-
42+
43+
/*
44+
If chrome not installed open itunes.
45+
*/
46+
public func checkInstalled() {
47+
if !self.appInstalled, let url = GoogleChrome.DownloadURL {
48+
Manager.open(url: url)
49+
}
50+
}
51+
3152
public func open(url: String, newTab: Bool = false,
3253
onSuccess: SuccessCallback? = nil, onFailure: FailureCallback? = nil, onCancel: CancelCallback? = nil) throws {
3354
var parameters = ["url": url]

Clients/Ulysses.swift

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//
2+
// Ulysses
3+
// CallbackURLKit
4+
/*
5+
The MIT License (MIT)
6+
Copyright (c) 2017 Eric Marchand (phimage)
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+
*/
23+
#if IMPORT
24+
import CallbackURLKit
25+
#endif
26+
import Foundation
27+
28+
/*
29+
Client for ulysses app https://ulyssesapp.com
30+
https://ulyssesapp.com/kb/x-callback-url/
31+
*/
32+
public class Ulysses: Client {
33+
34+
public enum UlyssesError: Int, FailureCallbackError {
35+
36+
case noAccessToken = 31
37+
38+
public var message: String {
39+
switch self {
40+
case .noAccessToken:
41+
return "No access token provided"
42+
}
43+
}
44+
45+
public var code: Int {
46+
return self.rawValue
47+
}
48+
49+
}
50+
51+
public init() {
52+
super.init(urlScheme: "ulysses")
53+
}
54+
55+
/*
56+
To protect the Ulysses library against access from malicious apps, actions that expose content or destructively change require the calling app to be authorized.
57+
58+
@param appName your app name
59+
@param onSuccess the success callback where you will receive the access-token as String.
60+
61+
Available since Ulysses 2.8 (API version 2).
62+
*/
63+
public func authorize(appName: String, onSuccess: @escaping (_ token: String) -> Void, onFailure: FailureCallback? = nil) throws {
64+
try self.perform(action: "authorize", parameters: ["appname": appName], onSuccess: { parameters in
65+
if let token = parameters?["access-token"] {
66+
onSuccess(token)
67+
} else {
68+
onFailure?(UlyssesError.noAccessToken)
69+
}
70+
}, onFailure: onFailure)
71+
}
72+
73+
/*
74+
Creates a new sheet.
75+
Available on iOS since Ulysses 2.6 (API version 1), on Mac since Ulysses 2.8 (API version 2).
76+
77+
@param text The contents that should be inserted to the new sheet. Must be URL-encoded. Contents are imported as Markdown by default.
78+
79+
@param group Optional. Specifies the group the new sheet should be inserted to. This argument can be set to one of the following values:
80+
- A group name (e.g. My Group) that will match the first group having the same name, regardless of its position in the group hierarchy.
81+
- A path to a particular target group (e.g. /My Group/My Subgroup). Any path must begin with a slash. (More…)
82+
- A unique identifier of the target group. (More…)
83+
If no value is given, the sheet is created inside the Inbox.
84+
@param format Optional. Specifies the format of the imported text: markdown, text, html. Defaults to Markdown.
85+
@param index Optional. The position of the new sheet in its parent group. Use 0 to make it the first sheet. Available since Ulysses 2.8 (API version 2).
86+
*/
87+
public func newSheet(text: String, group: String? = nil, format: String? = nil, index: String? = nil, onSuccess: SuccessCallback? = nil, onFailure: FailureCallback? = nil, onCancel: CancelCallback? = nil) throws {
88+
89+
var parameters = ["text": text]
90+
if let group = group {
91+
parameters["group"] = group
92+
}
93+
if let format = format {
94+
parameters["format"] = format
95+
}
96+
if let index = index {
97+
parameters["index"] = index
98+
}
99+
100+
try self.perform(action: "new-sheet", parameters: parameters, onSuccess: onSuccess, onCancel: onCancel)
101+
}
102+
103+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ to learn more.
167167
To get an already implemented [Clients](/Clients) use one of the subspec
168168
```ruby
169169
pod 'CallbackURLKit/GoogleChrome'
170+
pod 'CallbackURLKit/Ulysses' // https://ulyssesapp.com
170171
```
171172

172173
## Links

SampleApp/CallbackURLKitDemo/ViewController.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extension ViewController {
4141
try CallbackURLKitDemo.instance.printMessage(
4242
"a message %20 % = &toto=a",
4343
onSuccess: { parameters in
44-
print("parameters \(parameters)")
44+
print("parameters \(String(describing: parameters))")
4545
},
4646
onFailure: { error in
4747
print("\(error)")
@@ -56,6 +56,30 @@ extension ViewController {
5656
print("exception \(e)")
5757
}
5858
}
59+
60+
@IBAction func ulysseAuthorize(_ sender: AnyObject!) {
61+
let ulysses = Ulysses()
62+
do {
63+
try ulysses.authorize(
64+
appName: Manager.shared.callbackURLScheme ?? "callbackUrlKit",
65+
onSuccess: { token in
66+
print("token \(token)")
67+
},
68+
onFailure: { error in
69+
print("\(error)")
70+
}
71+
)
72+
73+
} catch CallbackURLKitError.appWithSchemeNotInstalled(let scheme) {
74+
print("chrome(\(scheme)) not installed or not implement x-callback-url in current os")
75+
76+
} catch CallbackURLKitError.callbackURLSchemeNotDefined {
77+
print("current app scheme not defined")
78+
} catch let e {
79+
print("exception \(e)")
80+
}
81+
}
82+
5983

6084
}
6185

SampleApp/CallbackURLKitDemoOSX/Base.lproj/Main.storyboard

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
33
<dependencies>
44
<deployment identifier="macosx"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
5+
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
6+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
67
</dependencies>
78
<scenes>
89
<!--Application-->
@@ -693,6 +694,17 @@
693694
<action selector="printAction:" target="XfG-lQ-9wD" id="TbD-AS-RPX"/>
694695
</connections>
695696
</button>
697+
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fPx-18-uxd">
698+
<rect key="frame" x="263" y="222" width="109" height="32"/>
699+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
700+
<buttonCell key="cell" type="push" title="UlysseAuth" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Vg-6j-pJj">
701+
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
702+
<font key="font" metaFont="system"/>
703+
</buttonCell>
704+
<connections>
705+
<action selector="ulysseAuthorize:" target="XfG-lQ-9wD" id="Mzo-Py-e5S"/>
706+
</connections>
707+
</button>
696708
</subviews>
697709
<constraints>
698710
<constraint firstItem="HN5-XY-tmg" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="20" id="74s-yQ-uTp"/>

SampleApp/Podfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ use_frameworks!
44
target 'CallbackURLKitDemo' do
55
platform :ios, '9.0'
66
pod 'CallbackURLKit/GoogleChrome', :path => '../CallbackURLKit.podspec'
7+
pod 'CallbackURLKit/Ulysses', :path => '../CallbackURLKit.podspec'
78
end
89

910
target 'CallbackURLKitDemoOSX' do
1011
platform :osx, '10.10'
1112
pod 'CallbackURLKit/GoogleChrome', :path => '../CallbackURLKit.podspec'
13+
pod 'CallbackURLKit/Ulysses', :path => '../CallbackURLKit.podspec'
1214
end

0 commit comments

Comments
 (0)