升级到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}\nRun 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}\nRun 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)