升级到iOS Beta 13之后,我注意到了一件不愉快的事情:我的应用有时会因传入的VoIP推送而崩溃。
在崩溃报告中,我看到以下内容:
iOS 13 Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP callback
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x1af21b9f0 __exceptionPreprocess
1 libobjc.A.dylib 0x1af7284fc objc_exception_throw
2 CoreFoundation 0x1af11efec +
[_CFXNotificationTokenRegistration keyCallbacks]
3 Foundation 0x1aeda1330 -[NSAssertionHandler
handleFailureInMethod:object:file:lineNumber:description:]
4 PushKit 0x19caa6b54 -[PKPushRegistry
_terminateAppIfThereAreUnhandledVoIPPushes]
5 libdispatch.dylib 0x1afa441ec _dispatch_client_callout
6 libdispatch.dylib 0x1af9f6c6c
_dispatch_lane_barrier_sync_invoke_and_complete
7 PushKit 0x19caa5b74 __73-[PKPushRegistry
voipPayloadReceived:mustPostCall:withCompletionHandler:]_block_invoke
8 libdispatch.dylib 0x1afa43678
_dispatch_call_block_and_release
9 libdispatch.dylib 0x1afa441ec
_dispatch_client_callout
10 libdispatch.dylib 0x1af9f61f8
_dispatch_main_queue_callback_4CF$VARIANT$mp
11 CoreFoundation 0x1af1992a0
CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE …
Run Code Online (Sandbox Code Playgroud) 我正在尝试将项目转换为使用RxSwift和MVVM.我有一个服务,在每个应用程序启动时同步来自Parse的数据列表,我基本上想确保我采取正确的方法.
我所做的是成为一个可变主题,然后允许我的模型听这个.ParseService:
let rx_parseMushrooms = Variable<[ParseMushroom]>([])
Run Code Online (Sandbox Code Playgroud)
MushroomLibraryModel:
_ = parseService.rx_parseMushrooms
.asObservable()
.map { (parseMushrooms:[ParseMushroom]) -> [Mushroom] in
let mushrooms = parseMushrooms.map { (parseMushroom:ParseMushroom) -> Mushroom in
let mushroom = Mapper<Mushroom>().map(parseMushroom.dictionaryWithValuesForKeys(parseMushroom.allKeys()))
return mushroom!
}
return mushrooms
}
.subscribeNext({ (mushrooms:[Mushroom]) -> Void in
self.mushrooms = mushrooms
print(mushrooms)
})
Run Code Online (Sandbox Code Playgroud)
我也是这样表达同步状态的.
ParseService:
struct SyncState {
enum State {
case Unsynced, ConnectingToServer, SyncingInfo, FetchingImageList, SyncingImages, SyncComplete, SyncCompleteWithError
}
var infoToSync = 0
var imagesToSync = 0
var imagesSynced = 0
var state = State.Unsynced
} …
Run Code Online (Sandbox Code Playgroud) CallKit的呼叫目录扩展名可用于阻止标准电话。但是,应该如何阻止VoIP呼叫与iOS 13一起使用?
When there is a VoIP call your app receives a VoIP push, but now with iOS 13 Apple are mandating that when the push is received the app must call CXProvider.reportNewIncomingCall()
.
However when reportNewIncomingCall() is called, the OS displays an incoming call screen (which is not the same as for a regular incoming call). It is apparently not possible for this call screen to be suppressed, and even if reportNewIncomminCall() is invoked with a parameter which is …
我已经在 iOS 中使用 VoIP PushKit 实现了用于音频和视频通话的 CallKit,它在 iOS 12 和之前的版本中运行良好,在 iOS 13 和 13.1 中也运行正常。
但它在两种情况下失败:
1)我们的应用程序处于前台状态。当蜂窝电话正在运行并且收到 VoIP 推送时,呼叫套件来电屏幕会显示 5 - 10 秒,然后蜂窝电话和 VOIP 通话都失败并显示“呼叫失败”警报。
2)我们的应用程序处于后台或已终止状态。当蜂窝电话正在运行并且收到 VoIP 推送时,蜂窝电话和 VOIP 通话都会失败,并显示“呼叫失败”警报。这次没有显示来电界面。
我在这里展示我的代码:
- (void)registerAppForVOIPPush {
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
Run Code Online (Sandbox Code Playgroud)
然后推送代表
#pragma mark PKPushRegistryDelegate ----
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials: (PKPushCredentials *)credentials forType:(NSString *)type {
NSString *newToken = [self hexadecimalStringFromData:credentials.token];
//Make a note of this token to a server to send VOIP for …
Run Code Online (Sandbox Code Playgroud) 我正在将 GoRouter 集成到我的 Flutter 应用程序中,我已经在使用 Riverpod。我有一个isAuthorizedProvider
定义如下:
final isAuthorizedProvider = Provider<bool>((ref) {
final authStateChanged = ref.watch(_authStateChangedProvider);
final user = authStateChanged.asData?.value;
return user != null;
});
Run Code Online (Sandbox Code Playgroud)
而且我不确定如何定义依赖于上面的 Provider 的 GoRouter。我想出了以下几点:
final goRouterProvider = Provider<GoRouter>((ref) => GoRouter(
debugLogDiagnostics: true,
redirect: (state) {
final isAuthorized = ref.watch(isAuthorizedProvider);
final isSigningIn = state.subloc == state.namedLocation('sign_in');
if (!isAuthorized) {
return isSigningIn ? null : state.namedLocation('sign_in');
}
// if the user is logged in but still on the login page, send them to
// the home …
Run Code Online (Sandbox Code Playgroud) 我想开发一个 SOS 应用程序。当我尝试使用 URL 架构 openURL() 时,它会显示一个警报,但我的要求是在尝试呼叫时连接呼叫而没有任何警报或弹出窗口。所以我找到了一个使用 CallKit 的解决方案。当我在我的应用程序中实现 CallKit 时,它不要求任何许可,拨出电话已发出,但被叫方没有接到任何电话。有什么解决办法吗?
我已经尝试了以下代码来连接呼叫。
@IBAction func buttonCallTapped(_ sender: Any) {
let provider = CXProvider(configuration: CXProviderConfiguration(localizedName: "My App"))
provider.setDelegate(self, queue: nil)
let controller = CXCallController()
let transaction = CXTransaction(action: CXStartCallAction(call: UUID(), handle: CXHandle(type: .phoneNumber, value: "\(number)")))
controller.request(transaction, completion: { error in })
DispatchQueue.main.asyncAfter(wallDeadline: DispatchWallTime.now() + 5) {
provider.reportOutgoingCall(with: controller.callObserver.calls[0].uuid, connectedAt: nil)
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用以下代码来接听视频通话。我的应用程序具有音频和视频通话功能,我使用的是 linphone + CallKit。
- (void)config {
CXProviderConfiguration *config = [[CXProviderConfiguration alloc]
initWithLocalizedName:[NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleName"]];
config.ringtoneSound = @"notes_of_the_optimistic.caf";
config.supportsVideo = TRUE;
config.iconTemplateImageData = UIImagePNGRepresentation([UIImage imageNamed:@"callkit_logo"]);
NSArray *ar = @[ [NSNumber numberWithInt:(int)CXHandleTypeGeneric] ];
NSSet *handleTypes = [[NSSet alloc] initWithArray:ar];
[config setSupportedHandleTypes:handleTypes];
[config setMaximumCallGroups:2];
[config setMaximumCallsPerCallGroup:1];
self.provider = [[CXProvider alloc] initWithConfiguration:config];
[self.provider setDelegate:self queue:dispatch_get_main_queue()];
}
- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video
{
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
update.supportsDTMF = TRUE;
update.supportsHolding = TRUE; …
Run Code Online (Sandbox Code Playgroud) 我已经实现了 Web RTC 并且它运行良好。问题是,当应用程序未打开\xe2\x80\x94或终止状态\xe2\x80\x94时,当我接到电话时,我无法将我的声音传递给其他用户,而我可以收听。我在 CXAnswer 调用委托之前配置了 AVAudioSession。
\n\nfunc configureAudioSession() {\n let sharedSession = AVAudioSession.sharedInstance()\n do {\n try sharedSession.setCategory(AVAudioSession.Category.playAndRecord)\n try sharedSession.setMode(AVAudioSession.Mode.voiceChat)\n try sharedSession.setPreferredIOBufferDuration(TimeInterval(0.005))\n try sharedSession.setPreferredSampleRate(44100.0)\n } catch {\n debugPrint("Failed to configure `AVAudioSession`")\n}\n
Run Code Online (Sandbox Code Playgroud)\n\nfunc provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {\n\n guard let call = ProviderDelegate.callManager.callWithUUID(action.callUUID) else {\n action.fail()\n return\n }\n\n configureAudioSession()\n\n call.answer { error in\n if let error = error {\n print("ERROR: failed to answer: \\(error.localizedDescription)")\n }\n action.fulfill()\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n 当用户结束从CallKit UI发出的呼叫时,应用程序将结束呼叫,并且实际的VOIP呼叫也将结束。但是,当我从自定义UI结束呼叫时,VOIP呼叫结束,但CallKit仍处于活动状态。如何从自定义UI结束CallKit会话?
当我在CallKit UI上按结束呼叫时,会发生以下情况:
func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
XCPjsua.shared()?.endCall()
action.fulfill()
}
Run Code Online (Sandbox Code Playgroud)
当我从自定义UI结束通话时会发生这种情况(我应该在这里关闭CallKit吗?):
- (void)endcall {
[[XCPjsua sharedXCPjsua] endCall];
}
Run Code Online (Sandbox Code Playgroud)