mirror of
https://github.com/grishka/NearDrop.git
synced 2026-04-03 09:46:19 +02:00
@@ -662,7 +662,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 2.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -688,7 +688,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 2.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -749,7 +749,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@@ -804,7 +804,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = macosx;
|
||||
@@ -823,7 +823,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 7;
|
||||
CURRENT_PROJECT_VERSION = 8;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_LSUIElement = YES;
|
||||
@@ -834,8 +834,8 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 2.0.3;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 2.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
@@ -855,7 +855,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 7;
|
||||
CURRENT_PROJECT_VERSION = 8;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_LSUIElement = YES;
|
||||
@@ -866,8 +866,8 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 2.0.3;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 2.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
@@ -885,7 +885,7 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
@@ -901,7 +901,7 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
||||
@@ -34,7 +34,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
}
|
||||
}
|
||||
nc.delegate=self
|
||||
let incomingTransfersCategory=NDNotificationCenterHackery.hackedNotificationCategory()
|
||||
let incomingTransfersCategory=UNNotificationCategory(identifier: "INCOMING_TRANSFERS", actions: [
|
||||
UNNotificationAction(identifier: "ACCEPT", title: NSLocalizedString("Accept", comment: ""), options: UNNotificationActionOptions.authenticationRequired),
|
||||
UNNotificationAction(identifier: "DECLINE", title: NSLocalizedString("Decline", comment: ""))
|
||||
], intentIdentifiers: [])
|
||||
let errorsCategory=UNNotificationCategory(identifier: "ERRORS", actions: [], intentIdentifiers: [])
|
||||
nc.setNotificationCategories([incomingTransfersCategory, errorsCategory])
|
||||
NearbyConnectionManager.shared.mainAppDelegate=self
|
||||
@@ -79,9 +82,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
}
|
||||
|
||||
func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo) {
|
||||
let notificationContent=UNMutableNotificationContent()
|
||||
notificationContent.title="NearDrop"
|
||||
notificationContent.subtitle=String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [transfer.pinCode!])
|
||||
let fileStr:String
|
||||
if let textTitle=transfer.textDescription{
|
||||
fileStr=textTitle
|
||||
@@ -90,14 +90,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
}else{
|
||||
fileStr=String.localizedStringWithFormat(NSLocalizedString("NFiles", value: "%d files", comment: ""), transfer.files.count)
|
||||
}
|
||||
let notificationContent=UNMutableNotificationContent()
|
||||
notificationContent.title="NearDrop"
|
||||
notificationContent.subtitle=String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [transfer.pinCode!])
|
||||
notificationContent.body=String(format: NSLocalizedString("DeviceSendingFiles", value: "%1$@ is sending you %2$@", comment: ""), arguments: [device.name, fileStr])
|
||||
notificationContent.sound = .default
|
||||
notificationContent.categoryIdentifier="INCOMING_TRANSFERS"
|
||||
notificationContent.userInfo=["transferID": transfer.id]
|
||||
NDNotificationCenterHackery.removeDefaultAction(notificationContent)
|
||||
if #available(macOS 11.0, *){
|
||||
NDNotificationCenterHackery.removeDefaultAction(notificationContent)
|
||||
}
|
||||
let notificationReq=UNNotificationRequest(identifier: "transfer_"+transfer.id, content: notificationContent, trigger: nil)
|
||||
self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer)
|
||||
UNUserNotificationCenter.current().add(notificationReq)
|
||||
self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer)
|
||||
}
|
||||
|
||||
func incomingTransfer(id: String, didFinishWith error: Error?) {
|
||||
@@ -107,8 +112,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
notificationContent.title=String(format: NSLocalizedString("TransferError", value: "Failed to receive files from %@", comment: ""), arguments: [transfer.device.name])
|
||||
if let ne=(error as? NearbyError){
|
||||
switch ne{
|
||||
case .inputOutput(let er):
|
||||
notificationContent.body=er.localizedDescription
|
||||
case .inputOutput:
|
||||
notificationContent.body="I/O Error";
|
||||
case .protocolError(_):
|
||||
notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "")
|
||||
case .requiredFieldMissing:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
|
||||
@@ -12,7 +12,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NDNotificationCenterHackery : NSObject
|
||||
|
||||
+ (UNNotificationCategory*)hackedNotificationCategory;
|
||||
+ (void)removeDefaultAction:(UNMutableNotificationContent*) content;
|
||||
|
||||
@end
|
||||
|
||||
@@ -35,13 +35,6 @@
|
||||
|
||||
@implementation NDNotificationCenterHackery
|
||||
|
||||
+ (UNNotificationCategory*)hackedNotificationCategory{
|
||||
UNNotificationAction *accept=[UNNotificationAction actionWithIdentifier:@"ACCEPT" title:NSLocalizedString(@"Accept", nil) options:0];
|
||||
UNNotificationAction *decline=[UNNotificationAction actionWithIdentifier:@"DECLINE" title:NSLocalizedString(@"Decline", nil) options:0];
|
||||
UNMutableNotificationCategory *category=[UNMutableNotificationCategory categoryWithIdentifier:@"INCOMING_TRANSFERS" actions:@[accept, decline] intentIdentifiers:@[] hiddenPreviewsBodyPlaceholder:@"" options: UNNotificationCategoryOptionCustomDismissAction];
|
||||
return category;
|
||||
}
|
||||
|
||||
+ (void)removeDefaultAction:(UNMutableNotificationContent*) content{
|
||||
content.hasDefaultAction=false;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ class InboundNearbyConnection: NearbyConnection{
|
||||
guard frame.payloadChunk.offset==currentOffset else { throw NearbyError.protocolError("Invalid offset into file \(frame.payloadChunk.offset), expected \(currentOffset)") }
|
||||
guard currentOffset+Int64(frame.payloadChunk.body.count)<=fileInfo.meta.size else { throw NearbyError.protocolError("Transferred file size exceeds previously specified value") }
|
||||
if frame.payloadChunk.body.count>0{
|
||||
try fileInfo.fileHandle?.write(contentsOf: frame.payloadChunk.body)
|
||||
fileInfo.fileHandle?.write(frame.payloadChunk.body)
|
||||
transferredFiles[id]!.bytesTransferred+=Int64(frame.payloadChunk.body.count)
|
||||
fileInfo.progress?.completedUnitCount=transferredFiles[id]!.bytesTransferred
|
||||
}else if (frame.payloadChunk.flags & 1)==1{
|
||||
|
||||
@@ -319,6 +319,31 @@ class NearbyConnection{
|
||||
return String(format: "%04d", abs(hash))
|
||||
}
|
||||
|
||||
internal static func hkdfExtract(salt:Data, ikm:Data) -> Data{
|
||||
return HMAC<SHA256>.authenticationCode(for: ikm, using: SymmetricKey(data: salt)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
|
||||
}
|
||||
|
||||
internal static func hkdfExpand(prk:Data, info:Data, length:Int) -> Data{
|
||||
var okm=Data()
|
||||
var t=Data()
|
||||
var i=0
|
||||
while okm.count<length{
|
||||
i=i+1
|
||||
let toDigest=t+info+Data([UInt8(truncatingIfNeeded: i)])
|
||||
t=HMAC<SHA256>.authenticationCode(for: toDigest, using: SymmetricKey(data: prk)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
|
||||
okm=okm+t
|
||||
}
|
||||
return okm.subdata(in: 0..<length)
|
||||
}
|
||||
|
||||
internal static func hkdf(inputKeyMaterial:SymmetricKey, salt:Data, info:Data, outputByteCount:Int) -> SymmetricKey{
|
||||
if #available(macOS 11.0, *){
|
||||
return HKDF<SHA256>.deriveKey(inputKeyMaterial: inputKeyMaterial, salt: salt, info: info, outputByteCount: outputByteCount)
|
||||
}else{
|
||||
return SymmetricKey(data: hkdfExpand(prk: hkdfExtract(salt: salt, ikm: inputKeyMaterial.withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})), info: info, length: outputByteCount))
|
||||
}
|
||||
}
|
||||
|
||||
internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{
|
||||
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") }
|
||||
|
||||
@@ -341,8 +366,8 @@ class NearbyConnection{
|
||||
var ukeyInfo=Data()
|
||||
ukeyInfo.append(ukeyClientInitMsgData!)
|
||||
ukeyInfo.append(ukeyServerInitMsgData!)
|
||||
let authString=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
||||
let nextSecret=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
||||
let authString=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
||||
let nextSecret=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
||||
|
||||
pinCode=NearbyConnection.pinCodeFromAuthKey(authString)
|
||||
|
||||
@@ -350,17 +375,17 @@ class NearbyConnection{
|
||||
0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D,
|
||||
0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10])
|
||||
|
||||
let d2dClientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
|
||||
let d2dServerKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
|
||||
let d2dClientKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
|
||||
let d2dServerKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
|
||||
|
||||
sha=SHA256()
|
||||
sha.update(data: "SecureMessage".data(using: .utf8)!)
|
||||
let smsgSalt=Data(sha.finalize())
|
||||
|
||||
let clientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
||||
let clientHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
||||
let serverKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
||||
let serverHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
||||
let clientKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
||||
let clientHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
||||
let serverKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
||||
let serverHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
||||
|
||||
if isServer(){
|
||||
decryptKey=clientKey
|
||||
|
||||
@@ -53,7 +53,7 @@ public enum NearbyError:Error{
|
||||
case protocolError(_ message:String)
|
||||
case requiredFieldMissing(_ message:String)
|
||||
case ukey2
|
||||
case inputOutput(cause:Errno)
|
||||
case inputOutput
|
||||
case canceled(reason:CancellationReason)
|
||||
|
||||
public enum CancellationReason{
|
||||
|
||||
@@ -277,9 +277,15 @@ class OutboundNearbyConnection:NearbyConnection{
|
||||
let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier
|
||||
meta.mimeType="application/octet-stream"
|
||||
if let typeID=typeID{
|
||||
let type=UTType(typeID)
|
||||
if let type=type, let mimeType=type.preferredMIMEType{
|
||||
meta.mimeType=mimeType
|
||||
if #available(macOS 11.0, *){
|
||||
let type=UTType(typeID)
|
||||
if let type=type, let mimeType=type.preferredMIMEType{
|
||||
meta.mimeType=mimeType
|
||||
}
|
||||
}else{
|
||||
if let mimeType=UTTypeCopyPreferredTagWithClass(typeID as CFString, kUTTagClassMIMEType){
|
||||
meta.mimeType=(mimeType.takeRetainedValue() as NSString) as String
|
||||
}
|
||||
}
|
||||
}
|
||||
if meta.mimeType.starts(with: "image/"){
|
||||
@@ -358,8 +364,14 @@ class OutboundNearbyConnection:NearbyConnection{
|
||||
currentTransfer=queue.removeFirst()
|
||||
}
|
||||
|
||||
guard let fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
|
||||
throw NearbyError.inputOutput(cause: Errno.ioError)
|
||||
let fileBuffer:Data
|
||||
if #available(macOS 10.15.4, *) {
|
||||
guard let _fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
|
||||
throw NearbyError.inputOutput
|
||||
}
|
||||
fileBuffer=_fileBuffer
|
||||
} else {
|
||||
fileBuffer=currentTransfer!.handle!.readData(ofLength: 512*1024)
|
||||
}
|
||||
|
||||
var transfer=Location_Nearby_Connections_PayloadTransferFrame()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -32,9 +32,6 @@
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NVE-vN-dkz">
|
||||
<rect key="frame" x="325" y="3" width="76" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="cP1-hK-9ZX"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Up-t3-mwm">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -42,6 +39,9 @@
|
||||
Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="cP1-hK-9ZX"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="cancel:" target="-2" id="Qav-AK-DGt"/>
|
||||
</connections>
|
||||
@@ -57,7 +57,7 @@ Gw
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NearDropIcon" id="q3u-Am-ZIA"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aNc-0i-CWK">
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aNc-0i-CWK">
|
||||
<rect key="frame" x="19" y="0.0" width="67" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="NearDrop" allowsEditingTextAttributes="YES" id="0xp-rC-2gr">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
@@ -83,7 +83,7 @@ Gw
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="jOq-9r-V1W"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OEz-QK-nem">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OEz-QK-nem">
|
||||
<rect key="frame" x="29" y="196" width="367" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" id="opy-Bj-x6u">
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -116,10 +116,10 @@ Gw
|
||||
<rect key="frame" x="0.0" y="0.0" width="521" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<progressIndicator maxValue="100" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="fCj-wF-rEj">
|
||||
<progressIndicator wantsLayer="YES" maxValue="100" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="fCj-wF-rEj">
|
||||
<rect key="frame" x="245" y="68" width="32" height="32"/>
|
||||
</progressIndicator>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="27P-yf-gUd">
|
||||
<textField wantsLayer="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="27P-yf-gUd">
|
||||
<rect key="frame" x="189" y="42" width="144" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Looking for devices..." id="NaJ-Wx-Pim">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
@@ -127,7 +127,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="V5W-Rm-YVM">
|
||||
<textField wantsLayer="YES" focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="V5W-Rm-YVM">
|
||||
<rect key="frame" x="-2" y="0.0" width="525" height="32"/>
|
||||
<textFieldCell key="cell" alignment="center" title="If you don't see your device, open "Google Files" app and tap "Receive" on the Nearby Share tab." id="vla-gF-eJo">
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -185,7 +185,7 @@ Gw
|
||||
<constraint firstAttribute="bottom" secondItem="84U-lB-SRB" secondAttribute="bottom" id="uh8-T1-Vd8"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dJc-gw-4ux">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dJc-gw-4ux">
|
||||
<rect key="frame" x="-2" y="56" width="388" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" alignment="center" id="QzI-qQ-OBb">
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -199,7 +199,7 @@ Gw
|
||||
<constraint firstAttribute="width" constant="200" id="bM2-Ih-2UC"/>
|
||||
</constraints>
|
||||
</progressIndicator>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="y8I-D3-scQ">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="y8I-D3-scQ">
|
||||
<rect key="frame" x="165" y="0.0" width="54" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" id="Iin-UY-IE5">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
||||
@@ -44,8 +44,17 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
|
||||
for attachment in attachments as NSArray{
|
||||
let provider=attachment as! NSItemProvider
|
||||
provider.loadItem(forTypeIdentifier: kUTTypeURL as String) { data, err in
|
||||
if let url=URL(dataRepresentation: data as! Data, relativeTo: nil, isAbsolute: false){
|
||||
self.urls.append(url)
|
||||
if let urlData=data as? Data{
|
||||
if let url=URL(dataRepresentation: urlData, relativeTo: nil, isAbsolute: false){
|
||||
self.urls.append(url)
|
||||
if self.urls.count==attachments.count{
|
||||
DispatchQueue.main.async {
|
||||
self.urlsReady()
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if let url=data as? NSURL{
|
||||
self.urls.append(url as URL)
|
||||
if self.urls.count==attachments.count{
|
||||
DispatchQueue.main.async {
|
||||
self.urlsReady()
|
||||
|
||||
Reference in New Issue
Block a user